From 1f06a12353d477d505b45d709a8a2c5630cbfcaa Mon Sep 17 00:00:00 2001 From: Florian Weik Date: Wed, 22 Aug 2018 22:40:25 +0200 Subject: [PATCH] core: clang-format most of the things. --- .clang-format | 5 - src/core/ComFixed.hpp | 2 +- src/core/EspressoSystemInterface.hpp | 3 +- src/core/Geometry.cpp | 3 +- src/core/Geometry.hpp | 24 +- src/core/PartCfg.hpp | 3 +- src/core/ParticleIterator.hpp | 4 +- src/core/PdbParser.cpp | 306 +- src/core/PdbParser.hpp | 83 +- src/core/RuntimeError.cpp | 6 +- src/core/RuntimeError.hpp | 3 +- src/core/RuntimeErrorCollector.cpp | 2 +- src/core/SystemInterface.cpp | 3 +- src/core/SystemInterface.hpp | 2 +- src/core/TabulatedPotential.hpp | 2 +- src/core/Vector.cpp | 3 +- src/core/accumulators/AccumulatorBase.hpp | 6 +- src/core/actor/Actor.hpp | 6 +- src/core/actor/ActorList.cpp | 10 +- src/core/actor/ActorList.hpp | 8 +- src/core/actor/DipolarBarnesHut.cpp | 47 +- src/core/actor/DipolarBarnesHut.hpp | 72 +- src/core/actor/DipolarDirectSum.cpp | 5 +- src/core/actor/DipolarDirectSum.hpp | 2 +- src/core/actor/HarmonicOrientationWell.cpp | 18 +- src/core/actor/HarmonicOrientationWell.hpp | 12 +- src/core/actor/HarmonicWell.cpp | 8 +- src/core/actor/HarmonicWell.hpp | 14 +- src/core/actor/Mmm1dgpuForce.cpp | 14 +- src/core/actor/Mmm1dgpuForce.hpp | 89 +- src/core/actor/mmm-common_cuda.hpp | 149 +- src/core/actor/specfunc_cuda.hpp | 229 +- src/core/algorithm/for_each_pair.hpp | 53 +- src/core/angle_cosine.cpp | 20 +- src/core/angle_cosine.hpp | 108 +- src/core/angle_cossquare.cpp | 22 +- src/core/angle_cossquare.hpp | 100 +- src/core/angle_harmonic.cpp | 22 +- src/core/angle_harmonic.hpp | 115 +- src/core/angledist.cpp | 12 +- src/core/bmhtf-nacl.cpp | 37 +- src/core/bmhtf-nacl.hpp | 9 +- src/core/bonded_coulomb.cpp | 21 +- src/core/bonded_coulomb.hpp | 50 +- src/core/bonded_coulomb_p3m_sr.cpp | 21 +- src/core/bonded_coulomb_p3m_sr.hpp | 58 +- src/core/buckingham.cpp | 7 +- src/core/cells.hpp | 8 +- src/core/cluster_analysis/Cluster.cpp | 147 +- src/core/cluster_analysis/Cluster.hpp | 55 +- .../cluster_analysis/ClusterStructure.cpp | 227 +- .../cluster_analysis/ClusterStructure.hpp | 41 +- src/core/collision.cpp | 4 +- src/core/communication.cpp | 18 +- src/core/communication.hpp | 16 +- .../constraints/HomogeneousMagneticField.cpp | 14 +- src/core/cos2.cpp | 32 +- src/core/cos2.hpp | 45 +- src/core/cuda_init.cpp | 70 +- src/core/cuda_init.hpp | 16 +- src/core/cuda_interface.cpp | 12 +- src/core/cuda_interface.hpp | 4 +- src/core/cuda_utils.hpp | 26 +- src/core/debug.cpp | 3 +- src/core/debye_hueckel.hpp | 10 +- src/core/dihedral.cpp | 21 +- src/core/dihedral.hpp | 121 +- src/core/dpd.cpp | 25 +- src/core/dpd.hpp | 25 +- src/core/elc.cpp | 13 +- src/core/elc.hpp | 4 +- src/core/electrokinetics.cpp | 3 +- src/core/electrokinetics.hpp | 91 +- src/core/electrokinetics_pdb_parse.cpp | 320 +- src/core/electrokinetics_pdb_parse.hpp | 20 +- src/core/energy.cpp | 45 +- src/core/energy.hpp | 19 +- src/core/energy_inline.hpp | 31 +- src/core/errorhandling.hpp | 4 +- src/core/fd-electrostatics.hpp | 88 +- src/core/fene.cpp | 29 +- src/core/fene.hpp | 101 +- src/core/fft-common.cpp | 456 +- src/core/fft-common.hpp | 114 +- src/core/fft-dipolar.cpp | 17 +- src/core/fft-dipolar.hpp | 33 +- src/core/fft.cpp | 486 +- src/core/fft.hpp | 23 +- src/core/field_coupling/couplings/Scaled.hpp | 4 +- src/core/forcecap.cpp | 6 +- src/core/forces.cpp | 4 +- src/core/forces.hpp | 19 +- src/core/forces_inline.hpp | 64 +- src/core/gaussian.cpp | 24 +- src/core/gaussian.hpp | 2 +- src/core/gb.cpp | 45 +- src/core/gb.hpp | 2 +- src/core/ghmc.cpp | 9 +- src/core/ghosts.cpp | 472 +- src/core/ghosts.hpp | 128 +- src/core/global.cpp | 288 +- src/core/grid.cpp | 4 +- src/core/grid.hpp | 22 +- src/core/halo.cpp | 302 +- src/core/halo.hpp | 76 +- src/core/harmonic.cpp | 21 +- src/core/harmonic.hpp | 78 +- src/core/harmonic_dumbbell.cpp | 30 +- src/core/harmonic_dumbbell.hpp | 107 +- src/core/hat.cpp | 23 +- src/core/hat.hpp | 2 +- src/core/hertzian.cpp | 24 +- src/core/hertzian.hpp | 4 +- src/core/iccp3m.cpp | 22 +- src/core/immersed_boundaries.cpp | 2 +- src/core/immersed_boundaries.hpp | 5 +- .../immersed_boundary/ImmersedBoundaries.cpp | 360 +- .../immersed_boundary/ImmersedBoundaries.hpp | 40 +- src/core/immersed_boundary/ibm_tribend.hpp | 8 +- src/core/immersed_boundary/ibm_triel.hpp | 11 +- src/core/initialize.cpp | 7 +- src/core/initialize.hpp | 12 +- src/core/integrate.cpp | 49 +- src/core/integrate.hpp | 24 +- src/core/interaction_data.cpp | 106 +- src/core/interaction_data.hpp | 53 +- src/core/io/mpiio/mpiio.cpp | 30 +- src/core/io/mpiio/mpiio.hpp | 13 +- src/core/io/writer/h5md/h5md_core.cpp | 30 +- src/core/io/writer/h5md/h5md_core.hpp | 22 +- src/core/lattice.cpp | 242 +- src/core/lattice.hpp | 172 +- src/core/layered.cpp | 3 +- src/core/layered.hpp | 18 +- src/core/lb-d3q19.cpp | 1 - src/core/lb.cpp | 42 +- src/core/lb.hpp | 41 +- src/core/lbboundaries.cpp | 4 +- src/core/lbboundaries.hpp | 11 +- src/core/lbboundaries/LBBoundary.cpp | 25 +- src/core/lbboundaries/LBBoundary.hpp | 32 +- src/core/lbgpu.cpp | 469 +- src/core/lbgpu.hpp | 128 +- src/core/lj.hpp | 10 +- src/core/ljcos.cpp | 42 +- src/core/ljcos.hpp | 6 +- src/core/ljcos2.cpp | 33 +- src/core/ljgen.cpp | 4 +- src/core/maggs.cpp | 2348 ++++---- src/core/maggs.hpp | 47 +- src/core/magnetic_non_p3m_methods.cpp | 6 +- src/core/mdlc_correction.cpp | 20 +- src/core/metadynamics.cpp | 12 +- src/core/minimize_energy.cpp | 4 +- src/core/minimize_energy.hpp | 13 +- src/core/mmm-common.cpp | 94 +- src/core/mmm-common.hpp | 30 +- src/core/mmm1d.hpp | 36 +- src/core/mmm2d.hpp | 62 +- src/core/molforces.cpp | 2 +- src/core/morse.cpp | 31 +- src/core/myconfig-default.hpp | 13 +- src/core/npt.cpp | 3 +- src/core/npt.hpp | 31 +- src/core/nsquare.hpp | 14 +- src/core/object-in-fluid/affinity.cpp | 38 +- src/core/object-in-fluid/affinity.hpp | 1423 +++-- .../object-in-fluid/membrane_collision.cpp | 26 +- .../object-in-fluid/membrane_collision.hpp | 143 +- .../object-in-fluid/oif_global_forces.cpp | 103 +- src/core/object-in-fluid/oif_local_forces.cpp | 32 +- src/core/object-in-fluid/oif_local_forces.hpp | 505 +- src/core/object-in-fluid/out_direction.cpp | 27 +- src/core/object-in-fluid/out_direction.hpp | 156 +- ...BFluxDensityProfileAtParticlePositions.cpp | 14 +- .../CylindricalLBProfileObservable.hpp | 4 +- .../CylindricalLBVelocityProfile.cpp | 8 +- ...alLBVelocityProfileAtParticlePositions.cpp | 11 +- src/core/observables/FluxDensityProfile.hpp | 7 +- src/core/observables/ForceDensityProfile.hpp | 7 +- src/core/observables/LBObservable.hpp | 19 +- src/core/observables/LBProfileObservable.hpp | 1 - src/core/observables/LBVelocityProfile.cpp | 23 +- .../not_yet_implemented/Average.hpp | 39 +- .../not_yet_implemented/BlockedComForce.hpp | 26 +- .../BlockedComPosition.hpp | 32 +- .../BlockedComVelocity.hpp | 32 +- .../not_yet_implemented/ComDipoleMoment.hpp | 20 +- .../not_yet_implemented/InteractsWith.hpp | 48 +- .../not_yet_implemented/LbDensityProfile.hpp | 106 +- .../not_yet_implemented/ParticleForce.hpp | 18 +- .../not_yet_implemented/PersistenceLength.hpp | 61 +- .../PolymerKDistribution.hpp | 72 +- .../RadialDensityDistribution.hpp | 229 +- .../RadialDensityProfile.hpp | 64 +- .../RadialFluxDensityProfile.hpp | 127 +- .../observables/not_yet_implemented/Rdf.hpp | 13 +- .../SpatialPolymerProperties.hpp | 34 +- .../not_yet_implemented/StructureFactor.hpp | 77 +- .../StructureFactorFast.hpp | 261 +- src/core/p3m-common.cpp | 334 +- src/core/p3m-common.hpp | 56 +- src/core/p3m-dipolar.cpp | 44 +- src/core/p3m-dipolar.hpp | 7 +- src/core/p3m.cpp | 71 +- src/core/p3m.hpp | 132 +- src/core/p3m_gpu.cpp | 3 +- src/core/p3m_gpu.hpp | 13 +- src/core/p3m_gpu_common.hpp | 69 +- src/core/p3m_gpu_error.hpp | 3 +- src/core/pair_criteria/pair_criteria.hpp | 126 +- src/core/partCfg_global.hpp | 4 +- src/core/particle_data.hpp | 2 +- src/core/polymer.cpp | 79 +- src/core/polymer.hpp | 21 +- src/core/polynom.cpp | 3 +- src/core/polynom.hpp | 44 +- src/core/pressure.cpp | 1297 +++-- src/core/pressure.hpp | 31 +- src/core/pressure_inline.hpp | 34 +- src/core/quartic.cpp | 22 +- src/core/quartic.hpp | 70 +- src/core/random.cpp | 13 +- src/core/random.hpp | 42 +- src/core/rattle.cpp | 10 +- src/core/rattle.hpp | 21 +- src/core/reaction_ensemble.cpp | 92 +- src/core/reaction_ensemble.hpp | 93 +- src/core/reaction_field.cpp | 33 +- src/core/reaction_field.hpp | 5 +- src/core/readpdb.cpp | 202 +- src/core/readpdb.hpp | 20 +- src/core/rotate_system.cpp | 2 +- src/core/rotation.cpp | 117 +- src/core/rotation.hpp | 42 +- src/core/scafacos.cpp | 116 +- src/core/scafacos.hpp | 30 +- src/core/scafacos/Scafacos.cpp | 120 +- src/core/scafacos/Scafacos.hpp | 72 +- src/core/shapes/Cylinder.cpp | 38 +- src/core/shapes/Cylinder.hpp | 6 +- src/core/shapes/Ellipsoid.cpp | 5 +- src/core/shapes/Ellipsoid.hpp | 3 +- src/core/shapes/Rhomboid.cpp | 49 +- src/core/shapes/Sphere.cpp | 1 - src/core/shapes/SpheroCylinder.cpp | 77 +- src/core/shapes/SpheroCylinder.hpp | 8 +- src/core/shapes/Stomatocyte.cpp | 61 +- src/core/shapes/Stomatocyte.hpp | 26 +- src/core/short_range_loop.hpp | 10 +- src/core/soft_sphere.cpp | 29 +- src/core/soft_sphere.hpp | 2 +- src/core/specfunc.cpp | 710 +-- src/core/specfunc.hpp | 63 +- src/core/statistics.cpp | 9 +- src/core/statistics.hpp | 6 +- src/core/statistics_chain.cpp | 111 +- src/core/statistics_chain.hpp | 111 +- src/core/statistics_cluster.cpp | 213 +- src/core/statistics_cluster.hpp | 62 +- src/core/statistics_fluid.hpp | 12 +- src/core/steppot.cpp | 40 +- src/core/steppot.hpp | 2 +- src/core/subt_lj.cpp | 18 +- src/core/swimmer_reaction.cpp | 57 +- src/core/swimmer_reaction.hpp | 18 +- src/core/thermalized_bond.cpp | 57 +- src/core/thermalized_bond.hpp | 118 +- src/core/thermostat.cpp | 39 +- src/core/thermostat.hpp | 22 +- src/core/thole.cpp | 25 +- src/core/thole.hpp | 109 +- src/core/tuning.cpp | 60 +- src/core/umbrella.cpp | 22 +- src/core/umbrella.hpp | 60 +- src/core/unit_tests/Batch_test.cpp | 25 +- src/core/unit_tests/Cache_test.cpp | 22 +- src/core/unit_tests/Factory_test.cpp | 24 +- src/core/unit_tests/ParticleCache_test.cpp | 2 +- src/core/unit_tests/ParticleIterator_test.cpp | 2 +- src/core/unit_tests/RunningAverage_test.cpp | 42 +- src/core/unit_tests/RuntimeError_test.cpp | 3 +- src/core/unit_tests/SkipIterator_test.cpp | 14 +- src/core/unit_tests/Span_test.cpp | 33 +- src/core/unit_tests/Variant_test.cpp | 5 +- src/core/unit_tests/accumulator.cpp | 12 +- src/core/unit_tests/for_each_pair_test.cpp | 2 +- src/core/unit_tests/gather_buffer_test.cpp | 14 +- src/core/unit_tests/get_value_test.cpp | 4 +- src/core/unit_tests/histogram.cpp | 4 +- src/core/unit_tests/keys_test.cpp | 3 +- src/core/unit_tests/mock/Cell.hpp | 2 +- src/core/unit_tests/mock/CellPList.hpp | 4 +- src/core/unit_tests/random_sequence.hpp | 5007 +++++++++-------- src/core/unit_tests/verlet_ia_test.cpp | 3 +- src/core/utils.cpp | 2 +- src/core/utils.hpp | 24 +- src/core/utils/Accumulator.hpp | 52 +- src/core/utils/Cache.hpp | 5 +- src/core/utils/Histogram.hpp | 38 +- src/core/utils/List.hpp | 3 +- src/core/utils/NoOp.hpp | 1 - src/core/utils/Span.hpp | 47 +- src/core/utils/checks/charge_neutrality.hpp | 5 +- src/core/utils/keys.hpp | 38 +- src/core/utils/make_unique.hpp | 3 +- src/core/utils/math/sqr.hpp | 5 +- src/core/utils/memory.hpp | 22 +- src/core/utils/mpi/detail/size_and_offset.hpp | 8 +- src/core/utils/mpi/gather_buffer.hpp | 6 +- src/core/utils/mpi/gatherv.hpp | 14 +- src/core/utils/mpi/scatter_buffer.hpp | 4 +- src/core/utils/parallel/Callback.hpp | 9 +- src/core/utils/parallel/ParallelObject.hpp | 6 +- .../serialization/CUDA_particle_data.hpp | 2 +- src/core/utils/serialization/List.hpp | 2 +- src/core/utils/serialization/ParticleList.hpp | 3 +- src/core/utils/statistics/RunningAverage.hpp | 9 +- src/core/virtual_sites.cpp | 281 +- src/core/virtual_sites.hpp | 13 +- src/core/virtual_sites/VirtualSites.hpp | 71 +- .../VirtualSitesInertialessTracers.cpp | 46 +- .../VirtualSitesInertialessTracers.hpp | 43 +- src/core/virtual_sites/VirtualSitesOff.hpp | 37 +- .../virtual_sites/VirtualSitesRelative.cpp | 243 +- .../virtual_sites/lb_inertialess_tracers.cpp | 34 +- .../lb_inertialess_tracers_cuda_interface.cpp | 6 +- .../lb_inertialess_tracers_cuda_interface.hpp | 6 +- src/core/virtual_sites/virtual_sites_com.cpp | 327 +- 329 files changed, 14324 insertions(+), 13116 deletions(-) diff --git a/.clang-format b/.clang-format index 21c0dd432d..3a5940ef65 100644 --- a/.clang-format +++ b/.clang-format @@ -36,8 +36,6 @@ BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: false @@ -55,12 +53,9 @@ IncludeCategories: Priority: 3 - Regex: '.*' Priority: 1 -IncludeIsMainRegex: '$' IndentCaseLabels: false IndentWidth: 2 IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: true MacroBlockBegin: '' MacroBlockEnd: '' diff --git a/src/core/ComFixed.hpp b/src/core/ComFixed.hpp index 080090cee4..e2040bd98f 100644 --- a/src/core/ComFixed.hpp +++ b/src/core/ComFixed.hpp @@ -22,8 +22,8 @@ #include "Vector.hpp" #include "utils/keys.hpp" -#include #include +#include #include #include diff --git a/src/core/EspressoSystemInterface.hpp b/src/core/EspressoSystemInterface.hpp index 47788a145d..332b3c2a47 100644 --- a/src/core/EspressoSystemInterface.hpp +++ b/src/core/EspressoSystemInterface.hpp @@ -165,8 +165,7 @@ class EspressoSystemInterface : public SystemInterface { : m_gpu_npart(0), m_gpu(false), m_r_gpu_begin(0), m_r_gpu_end(0), m_dip_gpu_begin(0), m_v_gpu_begin(0), m_v_gpu_end(0), m_q_gpu_begin(0), m_q_gpu_end(0), m_quatu_gpu_begin(0), m_quatu_gpu_end(0), - m_needsParticleStructGpu(false), m_splitParticleStructGpu(false) - {}; + m_needsParticleStructGpu(false), m_splitParticleStructGpu(false){}; virtual ~EspressoSystemInterface() {} void gatherParticles(); diff --git a/src/core/Geometry.cpp b/src/core/Geometry.cpp index 04124d0a7c..f57015e91d 100644 --- a/src/core/Geometry.cpp +++ b/src/core/Geometry.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "Geometry.hpp" - +#include "config.hpp" diff --git a/src/core/Geometry.hpp b/src/core/Geometry.hpp index 2dfe20a263..8722e200fc 100644 --- a/src/core/Geometry.hpp +++ b/src/core/Geometry.hpp @@ -1,16 +1,16 @@ #include "EspressoSystemInterface.hpp" class Geometry { - public: - void set_box_l(Vector3d x) {m_box_l =x;} - void set_my_left(Vector3d x) {m_my_left=x;} - void set_my_right(Vector3d x) { m_my_right=x;} - Vector3d get_box_l() {return m_box_l;} - Vector3d get_my_left() { return m_my_left; } - Vector3d get_my_right() { return m_my_right; } - private: - Vector3d m_box_l; - Vector3d m_my_left; - Vector3d m_my_right; -}; +public: + void set_box_l(Vector3d x) { m_box_l = x; } + void set_my_left(Vector3d x) { m_my_left = x; } + void set_my_right(Vector3d x) { m_my_right = x; } + Vector3d get_box_l() { return m_box_l; } + Vector3d get_my_left() { return m_my_left; } + Vector3d get_my_right() { return m_my_right; } +private: + Vector3d m_box_l; + Vector3d m_my_left; + Vector3d m_my_right; +}; diff --git a/src/core/PartCfg.hpp b/src/core/PartCfg.hpp index f493881936..c91d3b378c 100644 --- a/src/core/PartCfg.hpp +++ b/src/core/PartCfg.hpp @@ -30,8 +30,7 @@ class GetLocalParts { public: Range operator()() const { if (local_particles == nullptr) { - auto begin = - skip_it(nullptr, nullptr, SkipIfNullOrGhost()); + auto begin = skip_it(nullptr, nullptr, SkipIfNullOrGhost()); return Utils::make_range(make_indirect_iterator(begin), make_indirect_iterator(begin)); } diff --git a/src/core/ParticleIterator.hpp b/src/core/ParticleIterator.hpp index 0293802118..3b804ca921 100644 --- a/src/core/ParticleIterator.hpp +++ b/src/core/ParticleIterator.hpp @@ -20,9 +20,9 @@ struct ParticleIterator : public boost::iterator_facade< public: friend typename std::iterator_traits::difference_type distance(ParticleIterator const &begin, ParticleIterator const &end) { - if(begin == end) + if (begin == end) return 0; - + /* Remaining parts in this cell */ auto dist = ((*begin.m_cell)->n - begin.m_part_id); /* Now add the size of all cells between the next diff --git a/src/core/PdbParser.cpp b/src/core/PdbParser.cpp index 4cca029368..8a65037638 100644 --- a/src/core/PdbParser.cpp +++ b/src/core/PdbParser.cpp @@ -1,187 +1,191 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* vim: set ts=8 sts=2 sw=2 et: */ #include "PdbParser.hpp" -#include #include +#include using namespace std; namespace PdbParser { - BoundingBox PdbParser::calc_bounding_box() const { - BoundingBox bb; - - bb.llx = std::numeric_limits::max(); - bb.lly = std::numeric_limits::max(); - bb.llz = std::numeric_limits::max(); - bb.urx = -std::numeric_limits::max(); - bb.ury = -std::numeric_limits::max(); - bb.urz = -std::numeric_limits::max(); - - for(std::vector::const_iterator it = pdb_atoms.begin(); it != pdb_atoms.end(); ++it) { - bb.llx = std::min(it->x, bb.llx); - bb.lly = std::min(it->y, bb.lly); - bb.llz = std::min(it->z, bb.llz); - bb.urx = std::max(it->x, bb.urx); - bb.ury = std::max(it->y, bb.ury); - bb.urz = std::max(it->z, bb.urz); - } - return bb; +BoundingBox PdbParser::calc_bounding_box() const { + BoundingBox bb; + + bb.llx = std::numeric_limits::max(); + bb.lly = std::numeric_limits::max(); + bb.llz = std::numeric_limits::max(); + bb.urx = -std::numeric_limits::max(); + bb.ury = -std::numeric_limits::max(); + bb.urz = -std::numeric_limits::max(); + + for (std::vector::const_iterator it = pdb_atoms.begin(); + it != pdb_atoms.end(); ++it) { + bb.llx = std::min(it->x, bb.llx); + bb.lly = std::min(it->y, bb.lly); + bb.llz = std::min(it->z, bb.llz); + bb.urx = std::max(it->x, bb.urx); + bb.ury = std::max(it->y, bb.ury); + bb.urz = std::max(it->z, bb.urz); } + return bb; +} - bool PdbParser::parse_pdb_file(const string & filename) { - ifstream file; - string tmp; - pdb_atom a; - - pdb_atoms.clear(); +bool PdbParser::parse_pdb_file(const string &filename) { + ifstream file; + string tmp; + pdb_atom a; - try { - file.open(filename.c_str()); - while(file.good()) { - - file >> tmp; - if(tmp == "ATOM") { - file.ignore(246,' '); - file >> a.i; - file >> tmp >> tmp >> tmp >> tmp; - file >> a.x >> a.y >> a.z; - pdb_atoms.push_back(a); - } - } - } - catch (ifstream::failure& e) { - return false; - } + pdb_atoms.clear(); + + try { + file.open(filename.c_str()); + while (file.good()) { - return true; + file >> tmp; + if (tmp == "ATOM") { + file.ignore(246, ' '); + file >> a.i; + file >> tmp >> tmp >> tmp >> tmp; + file >> a.x >> a.y >> a.z; + pdb_atoms.push_back(a); + } + } + } catch (ifstream::failure &e) { + return false; } - bool PdbParser::parse_itp_file(const string & filename) { - ifstream file(filename.c_str()); - string tmp, buf; - itp_atom atom; - std::size_t pos; - - itp_atoms.clear(); - itp_atomtypes.clear(); - - while(file.good()) { - try { - buf = char(file.get()); - /* Skipp leading whitespace */ - if(std::isspace(buf[0])) - continue; - - /* Comment, ignore rest of line */ - if(buf[0] == ';') { - std::getline(file, buf); - continue; - } - - /* Section statement */ - if(buf == "[") { - std::getline(file, buf); - pos = buf.find_first_not_of(" \t["); - if(pos == std::string::npos) - continue; - - std::string section = buf.substr(pos, std::string::npos); - pos = section.find_first_of(']'); - section = section.substr(0, pos); - pos = section.find_last_not_of(" \t"); - section = section.substr(0, pos+1); - - if(section == "atoms") { - while(file.good()) { - buf = char(file.get()); - - /* Ignore leading whitespace, check for end of file (standard says EOF is "generaly" -1) */ - if(std::isspace(buf[0]) || (buf[0] == -1)) { - continue; - } - /* End of atoms section */ - if(buf[0] == '[') { - file.unget(); - break; - } - /* Comment, ignore line */ - if(buf[0] == ';') { - std::getline(file, buf); - continue; - } - /* Push back first char */ - file.unget(); - /* Parse line */ - std::getline(file, buf); - std::istringstream line(buf); - line >> atom.i >> atom.type >> tmp >> tmp >> tmp >> tmp >> atom.charge; - itp_atoms.insert(std::pair(atom.i, atom)); - } - } - if(section == "atomtypes") { - itp_atomtype type; - std::string type_name; - while(file.good()) { - buf = char(file.get()); - - /* Ignore leading whitespace */ - if(std::isspace(buf[0])) { - continue; - } - /* End of atoms section */ - if(buf[0] == '[') { - file.unget(); - break; - } - - /* Ignore leading whitespace, check for end of file (standard says EOF is "generaly" -1) */ - if(std::isspace(buf[0]) || (buf[0] == -1)) { - continue; - } - - /* Push back first char */ - file.unget(); - /* Parse line */ - std::getline(file, buf); - std::istringstream line(buf); - line >> type_name >> tmp >> tmp >> tmp >> tmp >> type.sigma >> type.epsilon; - /* Id is sequential number starting from zero */ - type.id = itp_atomtypes.size(); - itp_atomtypes.insert(std::pair(type_name, type)); - } - } - } + return true; +} + +bool PdbParser::parse_itp_file(const string &filename) { + ifstream file(filename.c_str()); + string tmp, buf; + itp_atom atom; + std::size_t pos; + + itp_atoms.clear(); + itp_atomtypes.clear(); + + while (file.good()) { + try { + buf = char(file.get()); + /* Skipp leading whitespace */ + if (std::isspace(buf[0])) + continue; + + /* Comment, ignore rest of line */ + if (buf[0] == ';') { + std::getline(file, buf); + continue; } - catch (...) { - return false; + + /* Section statement */ + if (buf == "[") { + std::getline(file, buf); + pos = buf.find_first_not_of(" \t["); + if (pos == std::string::npos) + continue; + + std::string section = buf.substr(pos, std::string::npos); + pos = section.find_first_of(']'); + section = section.substr(0, pos); + pos = section.find_last_not_of(" \t"); + section = section.substr(0, pos + 1); + + if (section == "atoms") { + while (file.good()) { + buf = char(file.get()); + + /* Ignore leading whitespace, check for end of file (standard says + * EOF is "generaly" -1) */ + if (std::isspace(buf[0]) || (buf[0] == -1)) { + continue; + } + /* End of atoms section */ + if (buf[0] == '[') { + file.unget(); + break; + } + /* Comment, ignore line */ + if (buf[0] == ';') { + std::getline(file, buf); + continue; + } + /* Push back first char */ + file.unget(); + /* Parse line */ + std::getline(file, buf); + std::istringstream line(buf); + line >> atom.i >> atom.type >> tmp >> tmp >> tmp >> tmp >> + atom.charge; + itp_atoms.insert(std::pair(atom.i, atom)); + } + } + if (section == "atomtypes") { + itp_atomtype type; + std::string type_name; + while (file.good()) { + buf = char(file.get()); + + /* Ignore leading whitespace */ + if (std::isspace(buf[0])) { + continue; + } + /* End of atoms section */ + if (buf[0] == '[') { + file.unget(); + break; + } + + /* Ignore leading whitespace, check for end of file (standard says + * EOF is "generaly" -1) */ + if (std::isspace(buf[0]) || (buf[0] == -1)) { + continue; + } + + /* Push back first char */ + file.unget(); + /* Parse line */ + std::getline(file, buf); + std::istringstream line(buf); + line >> type_name >> tmp >> tmp >> tmp >> tmp >> type.sigma >> + type.epsilon; + /* Id is sequential number starting from zero */ + type.id = itp_atomtypes.size(); + itp_atomtypes.insert( + std::pair(type_name, type)); + } + } } + } catch (...) { + return false; } - - return true; } - bool PdbParser::parse_file(const string & pdb_filename, const string & itp_filename) { - return parse_pdb_file(pdb_filename) && parse_itp_file(itp_filename); - } + return true; +} +bool PdbParser::parse_file(const string &pdb_filename, + const string &itp_filename) { + return parse_pdb_file(pdb_filename) && parse_itp_file(itp_filename); +} } diff --git a/src/core/PdbParser.hpp b/src/core/PdbParser.hpp index 9c61812b94..9cf13294ba 100644 --- a/src/core/PdbParser.hpp +++ b/src/core/PdbParser.hpp @@ -1,71 +1,74 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* vim: set ts=8 sts=2 sw=2 et: */ #ifndef __PDBPARSER_HPP #define __PDBPARSER_HPP -#include -#include -#include -#include #include +#include #include +#include +#include +#include namespace PdbParser { - struct BoundingBox { - float llx, lly, llz; - float urx, ury, urz; - }; +struct BoundingBox { + float llx, lly, llz; + float urx, ury, urz; +}; - typedef struct { - int i; // index - int m; // model index - float x,y,z; - } pdb_atom; +typedef struct { + int i; // index + int m; // model index + float x, y, z; +} pdb_atom; - typedef struct { - int i; - std::string type; - float charge; - } itp_atom; +typedef struct { + int i; + std::string type; + float charge; +} itp_atom; - typedef struct { - int id, espresso_id; - float sigma,epsilon; - } itp_atomtype; +typedef struct { + int id, espresso_id; + float sigma, epsilon; +} itp_atomtype; - struct itp_atomtype_compare { - bool operator() (const itp_atomtype &a, const itp_atomtype &b) { return a.id < b.id; } - }; +struct itp_atomtype_compare { + bool operator()(const itp_atomtype &a, const itp_atomtype &b) { + return a.id < b.id; + } +}; - class PdbParser { - public: - bool parse_pdb_file(const std::string & filename); - bool parse_itp_file(const std::string & filename); - bool parse_file(const std::string & pdb_filename, const std::string & itp_filename); - BoundingBox calc_bounding_box() const; - std::vector pdb_atoms; - std::map itp_atoms; - std::map itp_atomtypes; - }; +class PdbParser { +public: + bool parse_pdb_file(const std::string &filename); + bool parse_itp_file(const std::string &filename); + bool parse_file(const std::string &pdb_filename, + const std::string &itp_filename); + BoundingBox calc_bounding_box() const; + std::vector pdb_atoms; + std::map itp_atoms; + std::map itp_atomtypes; +}; } #endif diff --git a/src/core/RuntimeError.cpp b/src/core/RuntimeError.cpp index c3b89896c4..b16c95c7cd 100644 --- a/src/core/RuntimeError.cpp +++ b/src/core/RuntimeError.cpp @@ -19,8 +19,8 @@ #include "RuntimeError.hpp" -#include #include +#include namespace ErrorHandling { @@ -53,8 +53,6 @@ std::string RuntimeError::format() const { return ostr.str(); } -void RuntimeError::print() const { -std::cerr << format() << std::endl; -} +void RuntimeError::print() const { std::cerr << format() << std::endl; } } /* ErrorHandling */ diff --git a/src/core/RuntimeError.hpp b/src/core/RuntimeError.hpp index 787f5b9d58..ebd38d3917 100644 --- a/src/core/RuntimeError.hpp +++ b/src/core/RuntimeError.hpp @@ -61,8 +61,7 @@ struct RuntimeError { private: /** Boost serialization */ friend class boost::serialization::access; - template - void serialize(Archive &ar, const unsigned int) { + template void serialize(Archive &ar, const unsigned int) { ar &m_level; ar &m_who; ar &m_what; diff --git a/src/core/RuntimeErrorCollector.cpp b/src/core/RuntimeErrorCollector.cpp index 6339cb673d..b6606e700b 100644 --- a/src/core/RuntimeErrorCollector.cpp +++ b/src/core/RuntimeErrorCollector.cpp @@ -23,8 +23,8 @@ #include -#include #include +#include using namespace std; using boost::mpi::communicator; diff --git a/src/core/SystemInterface.cpp b/src/core/SystemInterface.cpp index 457218f395..5009ed55a2 100644 --- a/src/core/SystemInterface.cpp +++ b/src/core/SystemInterface.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "SystemInterface.hpp" - +#include "config.hpp" diff --git a/src/core/SystemInterface.hpp b/src/core/SystemInterface.hpp index e235616877..5f8d916a85 100644 --- a/src/core/SystemInterface.hpp +++ b/src/core/SystemInterface.hpp @@ -19,8 +19,8 @@ #ifndef SYSTEMINTERFACE_H #define SYSTEMINTERFACE_H -#include "config.hpp" #include "Vector.hpp" +#include "config.hpp" #include /** @todo: Turn needsXY in getter/setter **/ diff --git a/src/core/TabulatedPotential.hpp b/src/core/TabulatedPotential.hpp index 6e14b798a2..6d02303d63 100644 --- a/src/core/TabulatedPotential.hpp +++ b/src/core/TabulatedPotential.hpp @@ -7,8 +7,8 @@ #include #include -#include #include +#include struct TabulatedPotential { double minval = -1.0; diff --git a/src/core/Vector.cpp b/src/core/Vector.cpp index 6e1f234965..cac0308dde 100644 --- a/src/core/Vector.cpp +++ b/src/core/Vector.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "Vector.hpp" - +#include "config.hpp" diff --git a/src/core/accumulators/AccumulatorBase.hpp b/src/core/accumulators/AccumulatorBase.hpp index 1a6a88860a..381328e21c 100644 --- a/src/core/accumulators/AccumulatorBase.hpp +++ b/src/core/accumulators/AccumulatorBase.hpp @@ -5,11 +5,11 @@ namespace Accumulators { class AccumulatorBase { public: - explicit AccumulatorBase(int delta_N=1) - : m_delta_N(delta_N){}; + explicit AccumulatorBase(int delta_N = 1) : m_delta_N(delta_N){}; void auto_update(); - int &delta_N() {return m_delta_N;}; + int &delta_N() { return m_delta_N; }; virtual ~AccumulatorBase() {} + private: virtual void update() = 0; // Number of timesteps between automatic updates. diff --git a/src/core/actor/Actor.hpp b/src/core/actor/Actor.hpp index 10c7eb5fac..e123d7c647 100644 --- a/src/core/actor/Actor.hpp +++ b/src/core/actor/Actor.hpp @@ -27,9 +27,9 @@ */ class Actor { public: - virtual void computeForces(SystemInterface &s) { }; - virtual void computeTorques(SystemInterface &s) { }; - virtual void computeEnergy(SystemInterface &s) { }; + virtual void computeForces(SystemInterface &s){}; + virtual void computeTorques(SystemInterface &s){}; + virtual void computeEnergy(SystemInterface &s){}; virtual ~Actor() {} }; diff --git a/src/core/actor/ActorList.cpp b/src/core/actor/ActorList.cpp index 0bc2da8a45..63a2b652c4 100644 --- a/src/core/actor/ActorList.cpp +++ b/src/core/actor/ActorList.cpp @@ -21,12 +21,10 @@ #include #include -void ActorList::add(Actor *actor) { - this->push_back(actor); -} +void ActorList::add(Actor *actor) { this->push_back(actor); } void ActorList::remove(Actor *actor) { - iterator needle = std::find(this->begin(), this->end(), actor); - assert(needle != this->end()); - this->erase(needle); + iterator needle = std::find(this->begin(), this->end(), actor); + assert(needle != this->end()); + this->erase(needle); } diff --git a/src/core/actor/ActorList.hpp b/src/core/actor/ActorList.hpp index f2ade04869..4efc41787b 100644 --- a/src/core/actor/ActorList.hpp +++ b/src/core/actor/ActorList.hpp @@ -19,13 +19,13 @@ #ifndef _ACTOR_ACTORLIST_HPP #define _ACTOR_ACTORLIST_HPP -#include #include "Actor.hpp" +#include -class ActorList : public std::vector { +class ActorList : public std::vector { public: - void add(Actor *actor); - void remove(Actor *actor); + void add(Actor *actor); + void remove(Actor *actor); }; #endif /* ACTORLIST_HPP_ */ diff --git a/src/core/actor/DipolarBarnesHut.cpp b/src/core/actor/DipolarBarnesHut.cpp index afa0b6f0e0..022cbd0014 100644 --- a/src/core/actor/DipolarBarnesHut.cpp +++ b/src/core/actor/DipolarBarnesHut.cpp @@ -17,42 +17,39 @@ along with this program. If not, see . */ -#include "config.hpp" -#include "communication.hpp" -#include "grid.hpp" #include "DipolarBarnesHut.hpp" #include "../forces.hpp" #include "EspressoSystemInterface.hpp" -#include "forces.hpp" +#include "communication.hpp" +#include "config.hpp" #include "energy.hpp" +#include "forces.hpp" +#include "grid.hpp" #ifdef DIPOLAR_BARNES_HUT -void activate_dipolar_barnes_hut(float epssq, float itolsq) -{ - delete dipolarBarnesHut; - dipolarBarnesHut = nullptr; - // also necessary on 1 CPU or GPU, does more than just broadcasting - mpi_bcast_coulomb_params(); - dipolarBarnesHut = new DipolarBarnesHut(espressoSystemInterface, epssq, itolsq); - forceActors.push_back(dipolarBarnesHut); - energyActors.push_back(dipolarBarnesHut); - - coulomb.Dmethod = DIPOLAR_BH_GPU; +void activate_dipolar_barnes_hut(float epssq, float itolsq) { + delete dipolarBarnesHut; + dipolarBarnesHut = nullptr; + // also necessary on 1 CPU or GPU, does more than just broadcasting + mpi_bcast_coulomb_params(); + dipolarBarnesHut = + new DipolarBarnesHut(espressoSystemInterface, epssq, itolsq); + forceActors.push_back(dipolarBarnesHut); + energyActors.push_back(dipolarBarnesHut); + + coulomb.Dmethod = DIPOLAR_BH_GPU; } -void deactivate_dipolar_barnes_hut() -{ - if (dipolarBarnesHut) - { - forceActors.remove(dipolarBarnesHut); - energyActors.remove(dipolarBarnesHut); - } - delete dipolarBarnesHut; - dipolarBarnesHut = nullptr; +void deactivate_dipolar_barnes_hut() { + if (dipolarBarnesHut) { + forceActors.remove(dipolarBarnesHut); + energyActors.remove(dipolarBarnesHut); + } + delete dipolarBarnesHut; + dipolarBarnesHut = nullptr; } DipolarBarnesHut *dipolarBarnesHut = nullptr; #endif - diff --git a/src/core/actor/DipolarBarnesHut.hpp b/src/core/actor/DipolarBarnesHut.hpp index 67dfc2f201..ea221b83df 100644 --- a/src/core/actor/DipolarBarnesHut.hpp +++ b/src/core/actor/DipolarBarnesHut.hpp @@ -21,38 +21,40 @@ #ifdef DIPOLAR_BARNES_HUT -#include "errorhandling.hpp" -#include "SystemInterface.hpp" -#include "EspressoSystemInterface.hpp" -#include #include "Actor.hpp" #include "DipolarBarnesHut_cuda.cuh" -#include "grid.hpp" +#include "EspressoSystemInterface.hpp" +#include "SystemInterface.hpp" #include "cuda_interface.hpp" +#include "errorhandling.hpp" +#include "grid.hpp" #include "interaction_data.hpp" +#include #ifndef ACTOR_DIPOLARBARNESHUT_HPP #define ACTOR_DIPOLARBARNESHUT_HPP -//This needs to be done in the .cu file too +// This needs to be done in the .cu file too typedef float dds_float; class DipolarBarnesHut : public Actor { public: - DipolarBarnesHut(SystemInterface &s, float epssq, float itolsq) - { - k = coulomb.Dprefactor; - m_epssq = epssq; - m_itolsq = itolsq; - setBHPrecision(&m_epssq,&m_itolsq); - if(!s.requestFGpu()) - std::cerr << "DipolarBarnesHut needs access to forces on GPU!" << std::endl; - - if(!s.requestRGpu()) - std::cerr << "DipolarBarnesHut needs access to positions on GPU!" << std::endl; - - if(!s.requestDipGpu()) - std::cerr << "DipolarBarnesHut needs access to dipoles on GPU!" << std::endl; + DipolarBarnesHut(SystemInterface &s, float epssq, float itolsq) { + k = coulomb.Dprefactor; + m_epssq = epssq; + m_itolsq = itolsq; + setBHPrecision(&m_epssq, &m_itolsq); + if (!s.requestFGpu()) + std::cerr << "DipolarBarnesHut needs access to forces on GPU!" + << std::endl; + + if (!s.requestRGpu()) + std::cerr << "DipolarBarnesHut needs access to positions on GPU!" + << std::endl; + + if (!s.requestDipGpu()) + std::cerr << "DipolarBarnesHut needs access to dipoles on GPU!" + << std::endl; allocBHmemCopy(s.npart_gpu(), &m_bh_data); }; @@ -60,14 +62,16 @@ class DipolarBarnesHut : public Actor { void computeForces(SystemInterface &s) { fillConstantPointers(s.rGpuBegin(), s.dipGpuBegin(), m_bh_data); initBHgpu(m_bh_data.blocks); - buildBoxBH(m_bh_data.blocks); - buildTreeBH(m_bh_data.blocks); - summarizeBH(m_bh_data.blocks); - sortBH(m_bh_data.blocks); - if (forceBH(&m_bh_data,k,s.fGpuBegin(),s.torqueGpuBegin())) { - fprintf(stderr, "forceBH: some of kernels encounter the algorithm functional error"); - errexit(); - } + buildBoxBH(m_bh_data.blocks); + buildTreeBH(m_bh_data.blocks); + summarizeBH(m_bh_data.blocks); + sortBH(m_bh_data.blocks); + if (forceBH(&m_bh_data, k, s.fGpuBegin(), s.torqueGpuBegin())) { + fprintf( + stderr, + "forceBH: some of kernels encounter the algorithm functional error"); + errexit(); + } }; void computeEnergy(SystemInterface &s) { fillConstantPointers(s.rGpuBegin(), s.dipGpuBegin(), m_bh_data); @@ -76,17 +80,19 @@ class DipolarBarnesHut : public Actor { buildTreeBH(m_bh_data.blocks); summarizeBH(m_bh_data.blocks); sortBH(m_bh_data.blocks); - if (energyBH(&m_bh_data,k,(&(((CUDA_energy*)s.eGpu())->dipolar)))) { - fprintf(stderr, "energyBH: some of kernels encounter the algorithm functional error"); - errexit(); + if (energyBH(&m_bh_data, k, (&(((CUDA_energy *)s.eGpu())->dipolar)))) { + fprintf( + stderr, + "energyBH: some of kernels encounter the algorithm functional error"); + errexit(); } - }; + }; protected: float k; float m_epssq; float m_itolsq; - BHData m_bh_data = {0,0,0,0,0,0,0,0,0,0,0,0,0}; + BHData m_bh_data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; }; void activate_dipolar_barnes_hut(float epssq, float itolsq); diff --git a/src/core/actor/DipolarDirectSum.cpp b/src/core/actor/DipolarDirectSum.cpp index cbbc0ecb6c..adf2f23c59 100644 --- a/src/core/actor/DipolarDirectSum.cpp +++ b/src/core/actor/DipolarDirectSum.cpp @@ -1,8 +1,8 @@ #include "DipolarDirectSum.hpp" #include "EspressoSystemInterface.hpp" -#include "forces.hpp" #include "energy.hpp" +#include "forces.hpp" #include "utils/make_unique.hpp" @@ -15,7 +15,8 @@ void activate_dipolar_direct_sum_gpu() { coulomb.Dmethod = DIPOLAR_DS_GPU; mpi_bcast_coulomb_params(); - dipolarDirectSum = Utils::make_unique(espressoSystemInterface); + dipolarDirectSum = + Utils::make_unique(espressoSystemInterface); forceActors.push_back(dipolarDirectSum.get()); energyActors.push_back(dipolarDirectSum.get()); } diff --git a/src/core/actor/DipolarDirectSum.hpp b/src/core/actor/DipolarDirectSum.hpp index 2df95d4cc3..80e6e40bcb 100644 --- a/src/core/actor/DipolarDirectSum.hpp +++ b/src/core/actor/DipolarDirectSum.hpp @@ -6,8 +6,8 @@ #include "DipolarDirectSum_cuda.hpp" #include "SystemInterface.hpp" #include "cuda_interface.hpp" -#include "interaction_data.hpp" #include "grid.hpp" +#include "interaction_data.hpp" #include diff --git a/src/core/actor/HarmonicOrientationWell.cpp b/src/core/actor/HarmonicOrientationWell.cpp index 7cf475a61c..c20f782a1d 100644 --- a/src/core/actor/HarmonicOrientationWell.cpp +++ b/src/core/actor/HarmonicOrientationWell.cpp @@ -23,14 +23,16 @@ #ifdef CUDA #ifdef ROTATION -HarmonicOrientationWell:: -HarmonicOrientationWell(float x1, float x2, float x3, float _k, SystemInterface &s) - : x(x1), y(x2), z(x3), k(_k){ - if(!s.requestQuatuGpu()) - std::cerr << "HarmonicOrientationWell needs access to quatu on GPU!" << std::endl; - - if(!s.requestTorqueGpu()) - std::cerr << "HarmonicOrientationWell needs access to torques on GPU!" << std::endl; +HarmonicOrientationWell::HarmonicOrientationWell(float x1, float x2, float x3, + float _k, SystemInterface &s) + : x(x1), y(x2), z(x3), k(_k) { + if (!s.requestQuatuGpu()) + std::cerr << "HarmonicOrientationWell needs access to quatu on GPU!" + << std::endl; + + if (!s.requestTorqueGpu()) + std::cerr << "HarmonicOrientationWell needs access to torques on GPU!" + << std::endl; } #endif diff --git a/src/core/actor/HarmonicOrientationWell.hpp b/src/core/actor/HarmonicOrientationWell.hpp index 1e1b0cd732..0b8eecdef5 100644 --- a/src/core/actor/HarmonicOrientationWell.hpp +++ b/src/core/actor/HarmonicOrientationWell.hpp @@ -28,19 +28,23 @@ #include "SystemInterface.hpp" #include -void HarmonicOrientationWell_kernel_wrapper(float x, float y, float z, float k, int n, float *quatu, float *torque); +void HarmonicOrientationWell_kernel_wrapper(float x, float y, float z, float k, + int n, float *quatu, float *torque); class HarmonicOrientationWell : public Actor { public: - HarmonicOrientationWell(float x1, float x2, float x3, float _k, SystemInterface &s); + HarmonicOrientationWell(float x1, float x2, float x3, float _k, + SystemInterface &s); virtual void computeTorques(SystemInterface &s) { - HarmonicOrientationWell_kernel_wrapper(x,y,z,k,s.npart_gpu(), s.quatuGpuBegin(), s.torqueGpuBegin()); + HarmonicOrientationWell_kernel_wrapper( + x, y, z, k, s.npart_gpu(), s.quatuGpuBegin(), s.torqueGpuBegin()); }; virtual ~HarmonicOrientationWell() {} + protected: - float x,y,z; + float x, y, z; float k; }; diff --git a/src/core/actor/HarmonicWell.cpp b/src/core/actor/HarmonicWell.cpp index 5c186579c3..c139773a46 100644 --- a/src/core/actor/HarmonicWell.cpp +++ b/src/core/actor/HarmonicWell.cpp @@ -21,17 +21,17 @@ #include "forces.hpp" #ifdef CUDA -HarmonicWell:: -HarmonicWell(float x1, float x2, float x3, float _k, SystemInterface &s) { +HarmonicWell::HarmonicWell(float x1, float x2, float x3, float _k, + SystemInterface &s) { x = x1; y = x2; z = x3; k = _k; - if(!s.requestFGpu()) + if (!s.requestFGpu()) std::cerr << "HarmonicWell needs access to forces on GPU!" << std::endl; - if(!s.requestRGpu()) + if (!s.requestRGpu()) std::cerr << "HarmonicWell needs access to positions on GPU!" << std::endl; } diff --git a/src/core/actor/HarmonicWell.hpp b/src/core/actor/HarmonicWell.hpp index d3985aedff..f6a6a38577 100644 --- a/src/core/actor/HarmonicWell.hpp +++ b/src/core/actor/HarmonicWell.hpp @@ -27,25 +27,27 @@ #include "SystemInterface.hpp" #include -void HarmonicWell_kernel_wrapper(float x, float y, float z, float k, - int n, float *pos, float *f); +void HarmonicWell_kernel_wrapper(float x, float y, float z, float k, int n, + float *pos, float *f); class HarmonicWell : public Actor { public: HarmonicWell(float x1, float x2, float x3, float _k, SystemInterface &s); virtual void computeForces(SystemInterface &s) { - HarmonicWell_kernel_wrapper(x,y,z,k,s.npart_gpu(), - s.rGpuBegin(), s.fGpuBegin()); + HarmonicWell_kernel_wrapper(x, y, z, k, s.npart_gpu(), s.rGpuBegin(), + s.fGpuBegin()); }; virtual void computeEnergy(SystemInterface &s) { - std::cerr << "HarmonicWell does not currently support energies" << std::endl; + std::cerr << "HarmonicWell does not currently support energies" + << std::endl; }; virtual ~HarmonicWell() {} + protected: - float x,y,z; + float x, y, z; float k; }; diff --git a/src/core/actor/Mmm1dgpuForce.cpp b/src/core/actor/Mmm1dgpuForce.cpp index df7ae81c82..f590bc80fc 100644 --- a/src/core/actor/Mmm1dgpuForce.cpp +++ b/src/core/actor/Mmm1dgpuForce.cpp @@ -1,19 +1,17 @@ #include "actor/Mmm1dgpuForce.hpp" #include "EspressoSystemInterface.hpp" #include "communication.hpp" -#include "interaction_data.hpp" #include "forces.hpp" #include "grid.hpp" +#include "interaction_data.hpp" #ifdef MMM1D_GPU -void Mmm1dgpuForce::check_periodicity() -{ - if (PERIODIC(0) || PERIODIC(1) || !PERIODIC(2)) - { - std::cerr << "MMM1D requires periodicity (0,0,1)" << std::endl; - exit(EXIT_FAILURE); - } +void Mmm1dgpuForce::check_periodicity() { + if (PERIODIC(0) || PERIODIC(1) || !PERIODIC(2)) { + std::cerr << "MMM1D requires periodicity (0,0,1)" << std::endl; + exit(EXIT_FAILURE); + } } #endif diff --git a/src/core/actor/Mmm1dgpuForce.hpp b/src/core/actor/Mmm1dgpuForce.hpp index 77df8f0e4b..1a3a9825f4 100644 --- a/src/core/actor/Mmm1dgpuForce.hpp +++ b/src/core/actor/Mmm1dgpuForce.hpp @@ -1,73 +1,80 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #include "config.hpp" #ifdef MMM1D_GPU -#include "SystemInterface.hpp" #include "Actor.hpp" +#include "SystemInterface.hpp" #include typedef float mmm1dgpu_real; -class Mmm1dgpuForce : public Actor -{ +class Mmm1dgpuForce : public Actor { public: - // constructor - Mmm1dgpuForce(SystemInterface &s, mmm1dgpu_real coulomb_prefactor, mmm1dgpu_real maxPWerror, mmm1dgpu_real far_switch_radius = -1, int bessel_cutoff = -1); - ~Mmm1dgpuForce(); - // interface methods - void computeForces(SystemInterface &s); - void computeEnergy(SystemInterface &s); - // configuration methods - void setup(SystemInterface &s); - void tune(SystemInterface &s, mmm1dgpu_real _maxPWerror, mmm1dgpu_real _far_switch_radius, int _bessel_cutoff); - void set_params(mmm1dgpu_real _boxz, mmm1dgpu_real _coulomb_prefactor, mmm1dgpu_real _maxPWerror, mmm1dgpu_real _far_switch_radius, int _bessel_cutoff, bool manual = false); + // constructor + Mmm1dgpuForce(SystemInterface &s, mmm1dgpu_real coulomb_prefactor, + mmm1dgpu_real maxPWerror, mmm1dgpu_real far_switch_radius = -1, + int bessel_cutoff = -1); + ~Mmm1dgpuForce(); + // interface methods + void computeForces(SystemInterface &s); + void computeEnergy(SystemInterface &s); + // configuration methods + void setup(SystemInterface &s); + void tune(SystemInterface &s, mmm1dgpu_real _maxPWerror, + mmm1dgpu_real _far_switch_radius, int _bessel_cutoff); + void set_params(mmm1dgpu_real _boxz, mmm1dgpu_real _coulomb_prefactor, + mmm1dgpu_real _maxPWerror, mmm1dgpu_real _far_switch_radius, + int _bessel_cutoff, bool manual = false); private: - // CUDA parameters - unsigned int numThreads; - unsigned int numBlocks(SystemInterface &s); + // CUDA parameters + unsigned int numThreads; + unsigned int numBlocks(SystemInterface &s); + + // the box length currently set on the GPU + // Needed to make sure it hasn't been modified using setmd after inter coulomb + // was used. + mmm1dgpu_real host_boxz; + // the number of particles we had during the last run. Needed to check if we + // have to realloc dev_forcePairs + int host_npart; + bool need_tune; - // the box length currently set on the GPU - // Needed to make sure it hasn't been modified using setmd after inter coulomb was used. - mmm1dgpu_real host_boxz; - // the number of particles we had during the last run. Needed to check if we have to realloc dev_forcePairs - int host_npart; - bool need_tune; + // pairs==0: return forces using atomicAdd + // pairs==1: return force pairs + // pairs==2: return forces using a global memory reduction + int pairs; + // variables for forces and energies calculated pre-reduction + mmm1dgpu_real *dev_forcePairs, *dev_energyBlocks; - // pairs==0: return forces using atomicAdd - // pairs==1: return force pairs - // pairs==2: return forces using a global memory reduction - int pairs; - // variables for forces and energies calculated pre-reduction - mmm1dgpu_real *dev_forcePairs, *dev_energyBlocks; + // MMM1D parameters + mmm1dgpu_real coulomb_prefactor, maxPWerror, far_switch_radius; + int bessel_cutoff; - // MMM1D parameters - mmm1dgpu_real coulomb_prefactor, maxPWerror, far_switch_radius; - int bessel_cutoff; + // run a single force calculation and return the time it takes using + // high-precision CUDA timers + float force_benchmark(SystemInterface &s); - // run a single force calculation and return the time it takes using high-precision CUDA timers - float force_benchmark(SystemInterface &s); - - // some functions to move MPI dependencies out of the .cu file - void check_periodicity(); + // some functions to move MPI dependencies out of the .cu file + void check_periodicity(); }; #endif diff --git a/src/core/actor/mmm-common_cuda.hpp b/src/core/actor/mmm-common_cuda.hpp index c60b0cfdc7..88e89957e7 100644 --- a/src/core/actor/mmm-common_cuda.hpp +++ b/src/core/actor/mmm-common_cuda.hpp @@ -1,30 +1,31 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ +#include "cuda_utils.hpp" #include "mmm-common.hpp" #include "specfunc_cuda.hpp" -#include "cuda_utils.hpp" // order hardcoded. mmm1d_recalcTables() typically does order less than 30. -// As the coefficients are stored in __constant__ memory, the array needs to be sized in advance. +// As the coefficients are stored in __constant__ memory, the array needs to be +// sized in advance. // We don't know exactly how many coefficients per order, so we size plentiful. const int modpsi_order = 30; -const int modpsi_constant_size = modpsi_order*modpsi_order*2; +const int modpsi_constant_size = modpsi_order * modpsi_order * 2; // linearized array on host int *linModPsi_offsets = nullptr, *linModPsi_lengths = nullptr; @@ -32,77 +33,83 @@ mmm1dgpu_real *linModPsi = nullptr; // linearized array on device __constant__ int device_n_modPsi = 0; -__constant__ int device_linModPsi_offsets[2*modpsi_order], device_linModPsi_lengths[2*modpsi_order]; +__constant__ int device_linModPsi_offsets[2 * modpsi_order], + device_linModPsi_lengths[2 * modpsi_order]; __constant__ mmm1dgpu_real device_linModPsi[modpsi_constant_size]; -int modpsi_init() -{ - if (n_modPsi < modpsi_order) - { - create_mod_psi_up_to(modpsi_order); - } - - // linearize the coefficients array - linModPsi_offsets = (int*) Utils::realloc(linModPsi_offsets, sizeof(int) * 2*n_modPsi); - linModPsi_lengths = (int*) Utils::realloc(linModPsi_lengths, sizeof(int) * 2*n_modPsi); - for (int i = 0; i < 2*n_modPsi; i++) - { - if (i == 0) - linModPsi_offsets[i] = 0; - else - linModPsi_offsets[i] = linModPsi_offsets[i-1] + linModPsi_lengths[i-1]; - linModPsi_lengths[i] = modPsi[i].n; - } - linModPsi = (mmm1dgpu_real*) Utils::realloc(linModPsi, sizeof(mmm1dgpu_real) * (linModPsi_offsets[2*n_modPsi-1] + linModPsi_lengths[2*n_modPsi-1])); - for (int i = 0; i < 2*n_modPsi; i++) - { - for (int j = 0; j < modPsi[i].n; j++) - { - linModPsi[linModPsi_offsets[i] + j] = (mmm1dgpu_real) modPsi[i].e[j]; // cast to single-precision if necessary - } - } +int modpsi_init() { + if (n_modPsi < modpsi_order) { + create_mod_psi_up_to(modpsi_order); + } + + // linearize the coefficients array + linModPsi_offsets = + (int *)Utils::realloc(linModPsi_offsets, sizeof(int) * 2 * n_modPsi); + linModPsi_lengths = + (int *)Utils::realloc(linModPsi_lengths, sizeof(int) * 2 * n_modPsi); + for (int i = 0; i < 2 * n_modPsi; i++) { + if (i == 0) + linModPsi_offsets[i] = 0; + else + linModPsi_offsets[i] = + linModPsi_offsets[i - 1] + linModPsi_lengths[i - 1]; + linModPsi_lengths[i] = modPsi[i].n; + } + linModPsi = (mmm1dgpu_real *)Utils::realloc( + linModPsi, sizeof(mmm1dgpu_real) * (linModPsi_offsets[2 * n_modPsi - 1] + + linModPsi_lengths[2 * n_modPsi - 1])); + for (int i = 0; i < 2 * n_modPsi; i++) { + for (int j = 0; j < modPsi[i].n; j++) { + linModPsi[linModPsi_offsets[i] + j] = + (mmm1dgpu_real)modPsi[i] + .e[j]; // cast to single-precision if necessary + } + } + + for (int d = 0; d < deviceCount; d++) { + cudaSetDevice(d); - for (int d = 0; d < deviceCount; d++) - { - cudaSetDevice(d); - - // copy to GPU - int linModPsiSize = linModPsi_offsets[2*n_modPsi-1] + linModPsi_lengths[2*n_modPsi-1]; - if (linModPsiSize > modpsi_constant_size) - { - printf("ERROR: __constant__ device_linModPsi[] is not large enough\n"); - exit(EXIT_FAILURE); - } - cuda_safe_mem( cudaMemcpyToSymbol(device_linModPsi_offsets, linModPsi_offsets, 2*n_modPsi*sizeof(int)) ); - cuda_safe_mem( cudaMemcpyToSymbol(device_linModPsi_lengths, linModPsi_lengths, 2*n_modPsi*sizeof(int)) ); - cuda_safe_mem( cudaMemcpyToSymbol(device_linModPsi, linModPsi, linModPsiSize*sizeof(mmm1dgpu_real)) ); - cuda_safe_mem( cudaMemcpyToSymbol(device_n_modPsi, &n_modPsi, sizeof(int)) ); - } + // copy to GPU + int linModPsiSize = linModPsi_offsets[2 * n_modPsi - 1] + + linModPsi_lengths[2 * n_modPsi - 1]; + if (linModPsiSize > modpsi_constant_size) { + printf("ERROR: __constant__ device_linModPsi[] is not large enough\n"); + exit(EXIT_FAILURE); + } + cuda_safe_mem(cudaMemcpyToSymbol(device_linModPsi_offsets, + linModPsi_offsets, + 2 * n_modPsi * sizeof(int))); + cuda_safe_mem(cudaMemcpyToSymbol(device_linModPsi_lengths, + linModPsi_lengths, + 2 * n_modPsi * sizeof(int))); + cuda_safe_mem(cudaMemcpyToSymbol(device_linModPsi, linModPsi, + linModPsiSize * sizeof(mmm1dgpu_real))); + cuda_safe_mem(cudaMemcpyToSymbol(device_n_modPsi, &n_modPsi, sizeof(int))); + } - return 0; + return 0; } -int modpsi_destroy() -{ - // no need to delete the arrays off the device, they're in constant memory - // free arrays on host - free(linModPsi_offsets); - free(linModPsi_lengths); - free(linModPsi); - linModPsi_offsets = nullptr; - linModPsi_lengths = nullptr; - linModPsi = nullptr; - return 0; +int modpsi_destroy() { + // no need to delete the arrays off the device, they're in constant memory + // free arrays on host + free(linModPsi_offsets); + free(linModPsi_lengths); + free(linModPsi); + linModPsi_offsets = nullptr; + linModPsi_lengths = nullptr; + linModPsi = nullptr; + return 0; } -__device__ mmm1dgpu_real dev_mod_psi_even(int n, mmm1dgpu_real x) -{ - return evaluateAsTaylorSeriesAt(&device_linModPsi[device_linModPsi_offsets[2*n]], - device_linModPsi_lengths[2*n], x*x); +__device__ mmm1dgpu_real dev_mod_psi_even(int n, mmm1dgpu_real x) { + return evaluateAsTaylorSeriesAt( + &device_linModPsi[device_linModPsi_offsets[2 * n]], + device_linModPsi_lengths[2 * n], x * x); } -__device__ mmm1dgpu_real dev_mod_psi_odd(int n, mmm1dgpu_real x) -{ - return x*evaluateAsTaylorSeriesAt(&device_linModPsi[device_linModPsi_offsets[2*n+1]], - device_linModPsi_lengths[2*n+1], x*x); +__device__ mmm1dgpu_real dev_mod_psi_odd(int n, mmm1dgpu_real x) { + return x * evaluateAsTaylorSeriesAt( + &device_linModPsi[device_linModPsi_offsets[2 * n + 1]], + device_linModPsi_lengths[2 * n + 1], x * x); } diff --git a/src/core/actor/specfunc_cuda.hpp b/src/core/actor/specfunc_cuda.hpp index 4e947f542b..f02359587f 100644 --- a/src/core/actor/specfunc_cuda.hpp +++ b/src/core/actor/specfunc_cuda.hpp @@ -1,20 +1,20 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #include "config.hpp" @@ -23,191 +23,116 @@ const mmm1dgpu_real M_LN2f = M_LN2; // Adapted from specfunc.c and polynom.h __constant__ static mmm1dgpu_real bk0_data[11] = { - -.5 -0.03532739323390276872, - 0.3442898999246284869, - 0.03597993651536150163, - 0.00126461541144692592, - 0.00002286212103119451, - 0.00000025347910790261, - 0.00000000190451637722, - 0.00000000001034969525, - 0.00000000000004259816, - 0.00000000000000013744, - 0.00000000000000000035 -}; + -.5 - 0.03532739323390276872, 0.3442898999246284869, + 0.03597993651536150163, 0.00126461541144692592, + 0.00002286212103119451, 0.00000025347910790261, + 0.00000000190451637722, 0.00000000001034969525, + 0.00000000000004259816, 0.00000000000000013744, + 0.00000000000000000035}; __constant__ static int bk0_size = 11; __constant__ static mmm1dgpu_real ak0_data[17] = { - 2.5 -0.07643947903327941, - -0.02235652605699819, - 0.00077341811546938, - -0.00004281006688886, - 0.00000308170017386, - -0.00000026393672220, - 0.00000002563713036, - -0.00000000274270554, - 0.00000000031694296, - -0.00000000003902353, - 0.00000000000506804, - -0.00000000000068895, - 0.00000000000009744, - -0.00000000000001427, - 0.00000000000000215, - -0.00000000000000033, - 0.00000000000000005 -}; + 2.5 - 0.07643947903327941, -0.02235652605699819, 0.00077341811546938, + -0.00004281006688886, 0.00000308170017386, -0.00000026393672220, + 0.00000002563713036, -0.00000000274270554, 0.00000000031694296, + -0.00000000003902353, 0.00000000000506804, -0.00000000000068895, + 0.00000000000009744, -0.00000000000001427, 0.00000000000000215, + -0.00000000000000033, 0.00000000000000005}; __constant__ static int ak0_size = 16; __constant__ static mmm1dgpu_real ak02_data[14] = { - 2.5 -0.01201869826307592, - -0.00917485269102569, - 0.00014445509317750, - -0.00000401361417543, - 0.00000015678318108, - -0.00000000777011043, - 0.00000000046111825, - -0.00000000003158592, - 0.00000000000243501, - -0.00000000000020743, - 0.00000000000001925, - -0.00000000000000192, - 0.00000000000000020, - -0.00000000000000002 -}; + 2.5 - 0.01201869826307592, -0.00917485269102569, 0.00014445509317750, + -0.00000401361417543, 0.00000015678318108, -0.00000000777011043, + 0.00000000046111825, -0.00000000003158592, 0.00000000000243501, + -0.00000000000020743, 0.00000000000001925, -0.00000000000000192, + 0.00000000000000020, -0.00000000000000002}; __constant__ static int ak02_size = 13; __constant__ static mmm1dgpu_real bi0_data[12] = { - 5.5 -.07660547252839144951, - 1.92733795399380827000, - .22826445869203013390, - .01304891466707290428, - .00043442709008164874, - .00000942265768600193, - .00000014340062895106, - .00000000161384906966, - .00000000001396650044, - .00000000000009579451, - .00000000000000053339, - .00000000000000000245 -}; + 5.5 - .07660547252839144951, 1.92733795399380827000, .22826445869203013390, + .01304891466707290428, .00043442709008164874, .00000942265768600193, + .00000014340062895106, .00000000161384906966, .00000000001396650044, + .00000000000009579451, .00000000000000053339, .00000000000000000245}; __constant__ static int bi0_size = 12; __constant__ static mmm1dgpu_real bk1_data[11] = { - 1.5 +0.0253002273389477705, - -0.3531559607765448760, - -0.1226111808226571480, - -0.0069757238596398643, - -0.0001730288957513052, - -0.0000024334061415659, - -0.0000000221338763073, - -0.0000000001411488392, - -0.0000000000006666901, - -0.0000000000000024274, - -0.0000000000000000070 -}; + 1.5 + 0.0253002273389477705, -0.3531559607765448760, -0.1226111808226571480, + -0.0069757238596398643, -0.0001730288957513052, -0.0000024334061415659, + -0.0000000221338763073, -0.0000000001411488392, -0.0000000000006666901, + -0.0000000000000024274, -0.0000000000000000070}; __constant__ static int bk1_size = 11; __constant__ static mmm1dgpu_real ak1_data[17] = { - 2.5 +0.27443134069738830, - 0.07571989953199368, - -0.00144105155647540, - 0.00006650116955125, - -0.00000436998470952, - 0.00000035402774997, - -0.00000003311163779, - 0.00000000344597758, - -0.00000000038989323, - 0.00000000004720819, - -0.00000000000604783, - 0.00000000000081284, - -0.00000000000011386, - 0.00000000000001654, - -0.00000000000000248, - 0.00000000000000038, - -0.00000000000000006 -}; + 2.5 + 0.27443134069738830, 0.07571989953199368, -0.00144105155647540, + 0.00006650116955125, -0.00000436998470952, 0.00000035402774997, + -0.00000003311163779, 0.00000000344597758, -0.00000000038989323, + 0.00000000004720819, -0.00000000000604783, 0.00000000000081284, + -0.00000000000011386, 0.00000000000001654, -0.00000000000000248, + 0.00000000000000038, -0.00000000000000006}; __constant__ static int ak1_size = 17; __constant__ static mmm1dgpu_real ak12_data[14] = { - 2.5 +0.06379308343739001, - 0.02832887813049721, - -0.00024753706739052, - 0.00000577197245160, - -0.00000020689392195, - 0.00000000973998344, - -0.00000000055853361, - 0.00000000003732996, - -0.00000000000282505, - 0.00000000000023720, - -0.00000000000002176, - 0.00000000000000215, - -0.00000000000000022, - 0.00000000000000002 -}; + 2.5 + 0.06379308343739001, 0.02832887813049721, -0.00024753706739052, + 0.00000577197245160, -0.00000020689392195, 0.00000000973998344, + -0.00000000055853361, 0.00000000003732996, -0.00000000000282505, + 0.00000000000023720, -0.00000000000002176, 0.00000000000000215, + -0.00000000000000022, 0.00000000000000002}; __constant__ static int ak12_size = 14; __constant__ static mmm1dgpu_real bi1_data[11] = { - 1.75 -0.001971713261099859, - 0.407348876675464810, - 0.034838994299959456, - 0.001545394556300123, - 0.000041888521098377, - 0.000000764902676483, - 0.000000010042493924, - 0.000000000099322077, - 0.000000000000766380, - 0.000000000000004741, - 0.000000000000000024 -}; -__constant__ static int bi1_size = 11 ; - -__device__ mmm1dgpu_real evaluateAsChebychevSeriesAt(mmm1dgpu_real *c, int n, mmm1dgpu_real x) -{ + 1.75 - 0.001971713261099859, 0.407348876675464810, 0.034838994299959456, + 0.001545394556300123, 0.000041888521098377, 0.000000764902676483, + 0.000000010042493924, 0.000000000099322077, 0.000000000000766380, + 0.000000000000004741, 0.000000000000000024}; +__constant__ static int bi1_size = 11; + +__device__ mmm1dgpu_real evaluateAsChebychevSeriesAt(mmm1dgpu_real *c, int n, + mmm1dgpu_real x) { int j; mmm1dgpu_real x2 = 2 * x; mmm1dgpu_real dd = c[n - 1]; - mmm1dgpu_real d = x2*dd + c[n - 2]; - for(j = n - 3; j >= 1; j--) { + mmm1dgpu_real d = x2 * dd + c[n - 2]; + for (j = n - 3; j >= 1; j--) { mmm1dgpu_real tmp = d; - d = x2*d - dd + c[j]; + d = x2 * d - dd + c[j]; dd = tmp; } - return x*d - dd + c[0]/2; + return x * d - dd + c[0] / 2; } -__device__ mmm1dgpu_real evaluateAsTaylorSeriesAt(mmm1dgpu_real *c, int n, mmm1dgpu_real x) -{ +__device__ mmm1dgpu_real evaluateAsTaylorSeriesAt(mmm1dgpu_real *c, int n, + mmm1dgpu_real x) { int cnt = n - 1; mmm1dgpu_real r = c[cnt]; while (--cnt >= 0) - r = r*x + c[cnt]; + r = r * x + c[cnt]; return r; } -__device__ mmm1dgpu_real dev_K0(mmm1dgpu_real x) -{ - mmm1dgpu_real c = evaluateAsChebychevSeriesAt( - x<=2? bk0_data :x<=8? ak0_data : ak02_data, - x<=2? bk0_size :x<=8? ak0_size : ak02_size, - x<=2? x*x/2-1.0f :x<=8? (16/x-5.0f)/3.0f : (16/x-1.0f) - ); +__device__ mmm1dgpu_real dev_K0(mmm1dgpu_real x) { + mmm1dgpu_real c = evaluateAsChebychevSeriesAt( + x <= 2 ? bk0_data : x <= 8 ? ak0_data : ak02_data, + x <= 2 ? bk0_size : x <= 8 ? ak0_size : ak02_size, + x <= 2 ? x * x / 2 - 1.0f : x <= 8 ? (16 / x - 5.0f) / 3.0f + : (16 / x - 1.0f)); if (x <= 2) { - mmm1dgpu_real I0 = evaluateAsChebychevSeriesAt(bi0_data, bi0_size, x*x/4.5f-1.0f); - return (-log(x) + M_LN2f)*I0 + c; + mmm1dgpu_real I0 = + evaluateAsChebychevSeriesAt(bi0_data, bi0_size, x * x / 4.5f - 1.0f); + return (-log(x) + M_LN2f) * I0 + c; } - return exp(-x)*c*rsqrt(x); + return exp(-x) * c * rsqrt(x); } -__device__ mmm1dgpu_real dev_K1(mmm1dgpu_real x) -{ +__device__ mmm1dgpu_real dev_K1(mmm1dgpu_real x) { mmm1dgpu_real c = evaluateAsChebychevSeriesAt( - x<=2? bk1_data :x<=8? ak1_data : ak12_data, - x<=2? bk1_size :x<=8? ak1_size : ak12_size, - x<=2? x*x/2-1.0f :x<=8? (16/x-5.0f)/3.0f : (16/x-1.0f) - ); - if(x <= 2) { - mmm1dgpu_real I1 = x * evaluateAsChebychevSeriesAt(bi1_data, bi1_size, x*x/4.5f-1.0f); - return (log(x) - M_LN2f)*I1 + c/x; - } - return exp(-x)*c*rsqrt(x); + x <= 2 ? bk1_data : x <= 8 ? ak1_data : ak12_data, + x <= 2 ? bk1_size : x <= 8 ? ak1_size : ak12_size, + x <= 2 ? x * x / 2 - 1.0f : x <= 8 ? (16 / x - 5.0f) / 3.0f + : (16 / x - 1.0f)); + if (x <= 2) { + mmm1dgpu_real I1 = x * evaluateAsChebychevSeriesAt(bi1_data, bi1_size, + x * x / 4.5f - 1.0f); + return (log(x) - M_LN2f) * I1 + c / x; + } + return exp(-x) * c * rsqrt(x); } diff --git a/src/core/algorithm/for_each_pair.hpp b/src/core/algorithm/for_each_pair.hpp index 75a3977b91..752870aabc 100644 --- a/src/core/algorithm/for_each_pair.hpp +++ b/src/core/algorithm/for_each_pair.hpp @@ -7,32 +7,33 @@ #include "verlet_ia.hpp" namespace Algorithm { - /** - * @brief Run single and pair kernel for each particle (pair) from cell range. - * - * Iterates over all cells in [first, last), and calls particle_kernel for - * each particle in the cells. Then, for every particle pair within the - * cell and for each pair with the cells neighbors, distance_function is - * evaluated and verlet_criterion is evaluated with the calculated distance. - * Iff true, the pair_kernel is called. - * - * For details see verlet_ia and link_cell. - * - * Requirements on the types: - * The Cell type has to provide a function neighbors() that returns - * a cell range coprised of the topological neighbors of the cell, - * excluding the cell itself. The cells have to provide a m_verlet_list container - * that can be used to store particle pairs. It can be empty and is not touched - * if use_verlet_list is false. - * - * verlet_criterion(p1, p2, distance_function(p1, p2)) has to be valid and - * convertible to bool. - * - * ParticleKernel has to provide an ::operator() that can be called with a - * particle reference. - * PairKernel has to provide an ::operator() that can be called with two - * particle references an a distance. - */ +/** + * @brief Run single and pair kernel for each particle (pair) from cell range. + * + * Iterates over all cells in [first, last), and calls particle_kernel for + * each particle in the cells. Then, for every particle pair within the + * cell and for each pair with the cells neighbors, distance_function is + * evaluated and verlet_criterion is evaluated with the calculated distance. + * Iff true, the pair_kernel is called. + * + * For details see verlet_ia and link_cell. + * + * Requirements on the types: + * The Cell type has to provide a function neighbors() that returns + * a cell range coprised of the topological neighbors of the cell, + * excluding the cell itself. The cells have to provide a m_verlet_list + * container + * that can be used to store particle pairs. It can be empty and is not touched + * if use_verlet_list is false. + * + * verlet_criterion(p1, p2, distance_function(p1, p2)) has to be valid and + * convertible to bool. + * + * ParticleKernel has to provide an ::operator() that can be called with a + * particle reference. + * PairKernel has to provide an ::operator() that can be called with two + * particle references an a distance. + */ template void for_each_pair(CellIterator first, CellIterator last, diff --git a/src/core/angle_cosine.cpp b/src/core/angle_cosine.cpp index a3c498e971..9ef0d0ba24 100755 --- a/src/core/angle_cosine.cpp +++ b/src/core/angle_cosine.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file angle_cosine.cpp * @@ -32,9 +32,8 @@ \todo The type of the angle potential is chosen via config.hpp and cannot be changed at runtime. */ -int angle_cosine_set_params(int bond_type, double bend, double phi0) -{ - if(bond_type < 0) +int angle_cosine_set_params(int bond_type, double bend, double phi0) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -47,10 +46,9 @@ int angle_cosine_set_params(int bond_type, double bend, double phi0) bonded_ia_params[bond_type].num = 2; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } #endif - diff --git a/src/core/angle_cosine.hpp b/src/core/angle_cosine.hpp index 0354fa79a7..c4e8a23dde 100755 --- a/src/core/angle_cosine.hpp +++ b/src/core/angle_cosine.hpp @@ -1,34 +1,34 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef ANGLE_COSINE_H #define ANGLE_COSINE_H /** \file angle_cosine.hpp - * Routines to calculate the angle energy or/and and force + * Routines to calculate the angle energy or/and and force * for a particle triple. * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef BOND_ANGLE #include "grid.hpp" @@ -43,7 +43,7 @@ int angle_cosine_set_params(int bond_type, double bend, double phi0); /************************************************************/ /** Computes the three body angle interaction force and adds this - force to the particle forces. + force to the particle forces. @param p_mid Pointer to second/middle particle. @param p_left Pointer to first/left particle. @param p_right Pointer to third/right particle. @@ -52,36 +52,43 @@ int angle_cosine_set_params(int bond_type, double bend, double phi0); @param force2 returns force of particle 2 @return 0 */ -inline int calc_angle_cosine_force(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double force1[3], double force2[3]) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; +inline int calc_angle_cosine_force(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], double force2[3]) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_left to p_mid */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_mid to p_right */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - fac = iaparams->p.angle_cosine.bend; + fac = iaparams->p.angle_cosine.bend; - if ( cosine > TINY_COS_VALUE ) cosine = TINY_COS_VALUE; - if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE; - fac *= iaparams->p.angle_cosine.sin_phi0 * (cosine/sqrt(1-Utils::sqr(cosine))) + iaparams->p.angle_cosine.cos_phi0; - - for(j=0;j<3;j++) { + if (cosine > TINY_COS_VALUE) + cosine = TINY_COS_VALUE; + if (cosine < -TINY_COS_VALUE) + cosine = -TINY_COS_VALUE; + fac *= iaparams->p.angle_cosine.sin_phi0 * + (cosine / sqrt(1 - Utils::sqr(cosine))) + + iaparams->p.angle_cosine.cos_phi0; + + for (j = 0; j < 3; j++) { double f1 = fac * (cosine * vec1[j] - vec2[j]) * d1i; double f2 = fac * (cosine * vec2[j] - vec1[j]) * d2i; - force1[j] = (f1-f2); + force1[j] = (f1 - f2); force2[j] = -f1; } return 0; @@ -90,8 +97,10 @@ inline int calc_angle_cosine_force(Particle *p_mid, Particle *p_left, Particle * /* The force on each particle due to a three-body bonded potential is computed. */ inline void calc_angle_cosine_3body_forces(Particle *p_mid, Particle *p_left, - Particle *p_right, Bonded_ia_parameters *iaparams, - double force1[3], double force2[3], double force3[3]) { + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], double force2[3], + double force3[3]) { int j; double pot_dep; @@ -109,7 +118,7 @@ inline void calc_angle_cosine_3body_forces(Particle *p_mid, Particle *p_left, double fac; get_mi_vector(vec12, p_mid->r.p, p_left->r.p); - for(j = 0; j < 3; j++) + for (j = 0; j < 3; j++) vec21[j] = -vec12[j]; get_mi_vector(vec31, p_right->r.p, p_mid->r.p); @@ -120,9 +129,9 @@ inline void calc_angle_cosine_3body_forces(Particle *p_mid, Particle *p_left, cos_phi = scalar(vec21, vec31) / (vec21_magn * vec31_magn); sin_phi = sqrt(1.0 - Utils::sqr(cos_phi)); - /* uncomment this block if interested in the angle + /* uncomment this block if interested in the angle if(cos_phi < -1.0) cos_phi = -TINY_COS_VALUE; - if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; + if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; phi = acos(cos_phi); */ @@ -133,27 +142,28 @@ inline void calc_angle_cosine_3body_forces(Particle *p_mid, Particle *p_left, cos_phi0 = iaparams->p.angle_cosine.cos_phi0; // potential dependent term [dU/dphi = K * sin(phi - phi0)] - // trig identity: sin(a - b) = sin(a)cos(b) - cos(a)sin(b) + // trig identity: sin(a - b) = sin(a)cos(b) - cos(a)sin(b) pot_dep = K * (sin_phi * cos_phi0 - cos_phi * sin_phi0); } fac = pot_dep / sin_phi; - for(j = 0; j < 3; j++) { - fj[j] = vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; - fk[j] = vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; + for (j = 0; j < 3; j++) { + fj[j] = + vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; + fk[j] = + vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; } // note that F1 = -(F2 + F3) - for(j = 0; j < 3; j++) { + for (j = 0; j < 3; j++) { force1[j] = force1[j] - fac * (fj[j] + fk[j]); force2[j] = force2[j] + fac * fj[j]; force3[j] = force3[j] + fac * fk[j]; } } - -/** Computes the three body angle interaction energy. +/** Computes the three body angle interaction energy. @param p_mid Pointer to first particle. @param p_left Pointer to second/middle particle. @param p_right Pointer to third particle. @@ -161,30 +171,38 @@ inline void calc_angle_cosine_3body_forces(Particle *p_mid, Particle *p_left, @param _energy return energy pointer. @return 0. */ -inline int angle_cosine_energy(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double *_energy) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2; +inline int angle_cosine_energy(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double *_energy) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_mid to p_left */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_right to p_mid */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - if ( cosine > TINY_COS_VALUE) cosine = TINY_COS_VALUE; - if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE; + if (cosine > TINY_COS_VALUE) + cosine = TINY_COS_VALUE; + if (cosine < -TINY_COS_VALUE) + cosine = -TINY_COS_VALUE; /* bond angle energy */ - *_energy = iaparams->p.angle_cosine.bend*(cosine*iaparams->p.angle_cosine.cos_phi0 - sqrt(1-Utils::sqr(cosine))*iaparams->p.angle_cosine.sin_phi0+1); + *_energy = + iaparams->p.angle_cosine.bend * + (cosine * iaparams->p.angle_cosine.cos_phi0 - + sqrt(1 - Utils::sqr(cosine)) * iaparams->p.angle_cosine.sin_phi0 + 1); return 0; } diff --git a/src/core/angle_cossquare.cpp b/src/core/angle_cossquare.cpp index 7c748026e8..0e4245528f 100755 --- a/src/core/angle_cossquare.cpp +++ b/src/core/angle_cossquare.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file angle_cossquare.cpp * @@ -32,9 +32,8 @@ \todo The type of the angle potential is chosen via config.hpp and cannot be changed at runtime. */ -int angle_cossquare_set_params(int bond_type, double bend, double phi0) -{ - if(bond_type < 0) +int angle_cossquare_set_params(int bond_type, double bend, double phi0) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -44,12 +43,11 @@ int angle_cossquare_set_params(int bond_type, double bend, double phi0) bonded_ia_params[bond_type].p.angle_cossquare.cos_phi0 = cos(phi0); bonded_ia_params[bond_type].type = BONDED_IA_ANGLE_COSSQUARE; bonded_ia_params[bond_type].num = 2; - + /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } #endif - diff --git a/src/core/angle_cossquare.hpp b/src/core/angle_cossquare.hpp index 582abad36a..1d68749e69 100755 --- a/src/core/angle_cossquare.hpp +++ b/src/core/angle_cossquare.hpp @@ -1,34 +1,34 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef ANGLE_COSSQUARE_H #define ANGLE_COSSQUARE_H /** \file angle_cossquare.hpp - * Routines to calculate the angle energy or/and and force + * Routines to calculate the angle energy or/and and force * for a particle triple. * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef BOND_ANGLE #include "grid.hpp" @@ -43,7 +43,7 @@ int angle_cossquare_set_params(int bond_type, double bend, double phi0); /************************************************************/ /** Computes the three body angle interaction force and adds this - force to the particle forces. + force to the particle forces. @param p_mid Pointer to second/middle particle. @param p_left Pointer to first/left particle. @param p_right Pointer to third/right particle. @@ -52,34 +52,37 @@ int angle_cossquare_set_params(int bond_type, double bend, double phi0); @param force2 returns force of particle 2 @return 0 */ -inline int calc_angle_cossquare_force(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double force1[3], double force2[3]) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; +inline int calc_angle_cossquare_force(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], double force2[3]) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_left to p_mid */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_mid to p_right */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - fac = iaparams->p.angle_cossquare.bend; + fac = iaparams->p.angle_cossquare.bend; fac *= iaparams->p.angle_cossquare.cos_phi0 + cosine; - - for(j=0;j<3;j++) { + + for (j = 0; j < 3; j++) { double f1 = fac * (cosine * vec1[j] - vec2[j]) * d1i; double f2 = fac * (cosine * vec2[j] - vec1[j]) * d2i; - force1[j] = (f1-f2); + force1[j] = (f1 - f2); force2[j] = -f1; } return 0; @@ -88,8 +91,11 @@ inline int calc_angle_cossquare_force(Particle *p_mid, Particle *p_left, Particl /* The force on each particle due to a three-body bonded potential is computed. */ inline void calc_angle_cossquare_3body_forces(Particle *p_mid, Particle *p_left, - Particle *p_right, Bonded_ia_parameters *iaparams, - double force1[3], double force2[3], double force3[3]) { + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], + double force2[3], + double force3[3]) { int j; double pot_dep; @@ -107,7 +113,7 @@ inline void calc_angle_cossquare_3body_forces(Particle *p_mid, Particle *p_left, double fac; get_mi_vector(vec12, p_mid->r.p, p_left->r.p); - for(j = 0; j < 3; j++) + for (j = 0; j < 3; j++) vec21[j] = -vec12[j]; get_mi_vector(vec31, p_right->r.p, p_mid->r.p); @@ -118,37 +124,39 @@ inline void calc_angle_cossquare_3body_forces(Particle *p_mid, Particle *p_left, cos_phi = scalar(vec21, vec31) / (vec21_magn * vec31_magn); sin_phi = sqrt(1.0 - Utils::sqr(cos_phi)); - /* uncomment this block if interested in the angle + /* uncomment this block if interested in the angle if(cos_phi < -1.0) cos_phi = -TINY_COS_VALUE; - if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; + if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; phi = acos(cos_phi); */ { double K, cos_phi0; K = iaparams->p.angle_cossquare.bend; cos_phi0 = iaparams->p.angle_cossquare.cos_phi0; - - // potential dependent term [dU/dphi = K * (sin_phi * cos_phi0 - cos_phi * sin_phi)] + + // potential dependent term [dU/dphi = K * (sin_phi * cos_phi0 - cos_phi * + // sin_phi)] pot_dep = K * (sin_phi * cos_phi0 - cos_phi * sin_phi); } fac = pot_dep / sin_phi; - for(j = 0; j < 3; j++) { - fj[j] = vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; - fk[j] = vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; + for (j = 0; j < 3; j++) { + fj[j] = + vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; + fk[j] = + vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; } // note that F1 = -(F2 + F3) - for(j = 0; j < 3; j++) { + for (j = 0; j < 3; j++) { force1[j] = force1[j] - fac * (fj[j] + fk[j]); force2[j] = force2[j] + fac * fj[j]; force3[j] = force3[j] + fac * fk[j]; } } - -/** Computes the three body angle interaction energy. +/** Computes the three body angle interaction energy. @param p_mid Pointer to first particle. @param p_left Pointer to second/middle particle. @param p_right Pointer to third particle. @@ -156,29 +164,35 @@ inline void calc_angle_cossquare_3body_forces(Particle *p_mid, Particle *p_left, @param _energy return energy pointer. @return 0. */ -inline int angle_cossquare_energy(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double *_energy) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2; +inline int angle_cossquare_energy(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double *_energy) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_mid to p_left */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_right to p_mid */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - if ( cosine > TINY_COS_VALUE) cosine = TINY_COS_VALUE; - if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE; + if (cosine > TINY_COS_VALUE) + cosine = TINY_COS_VALUE; + if (cosine < -TINY_COS_VALUE) + cosine = -TINY_COS_VALUE; /* bond angle energy */ - *_energy = 0.5*iaparams->p.angle_cossquare.bend*Utils::sqr(cosine + iaparams->p.angle_cossquare.cos_phi0); + *_energy = 0.5 * iaparams->p.angle_cossquare.bend * + Utils::sqr(cosine + iaparams->p.angle_cossquare.cos_phi0); return 0; } diff --git a/src/core/angle_harmonic.cpp b/src/core/angle_harmonic.cpp index 374591dd44..587974a46b 100755 --- a/src/core/angle_harmonic.cpp +++ b/src/core/angle_harmonic.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file angle_harmonic.cpp * @@ -32,9 +32,8 @@ \todo The type of the angle potential is chosen via config.hpp and cannot be changed at runtime. */ -int angle_harmonic_set_params(int bond_type, double bend, double phi0) -{ - if(bond_type < 0) +int angle_harmonic_set_params(int bond_type, double bend, double phi0) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -44,12 +43,11 @@ int angle_harmonic_set_params(int bond_type, double bend, double phi0) bonded_ia_params[bond_type].type = BONDED_IA_ANGLE_HARMONIC; bonded_ia_params[bond_type].num = 2; - + /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } #endif - diff --git a/src/core/angle_harmonic.hpp b/src/core/angle_harmonic.hpp index fe15281a3c..318d0c173e 100755 --- a/src/core/angle_harmonic.hpp +++ b/src/core/angle_harmonic.hpp @@ -1,34 +1,34 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef ANGLE_HARMONIC_H #define ANGLE_HARMONIC_H /** \file angle_harmonic.hpp - * Routines to calculate the angle energy or/and and force + * Routines to calculate the angle energy or/and and force * for a particle triple. * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef BOND_ANGLE #include "grid.hpp" @@ -43,7 +43,7 @@ int angle_harmonic_set_params(int bond_type, double bend, double phi0); /************************************************************/ /** Computes the three body angle interaction force and adds this - force to the particle forces. + force to the particle forces. @param p_mid Pointer to second/middle particle. @param p_left Pointer to first/left particle. @param p_right Pointer to third/right particle. @@ -52,43 +52,49 @@ int angle_harmonic_set_params(int bond_type, double bend, double phi0); @param force2 returns force of particle 2 @return 0 */ -inline int calc_angle_harmonic_force(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double force1[3], double force2[3]) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; +inline int calc_angle_harmonic_force(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], double force2[3]) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2, fac; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_left to p_mid */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_mid to p_right */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - fac = iaparams->p.angle_harmonic.bend; + fac = iaparams->p.angle_harmonic.bend; { - double phi,sinphi; - if ( cosine > TINY_COS_VALUE) cosine = TINY_COS_VALUE; - if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE; - phi = acos(-cosine); + double phi, sinphi; + if (cosine > TINY_COS_VALUE) + cosine = TINY_COS_VALUE; + if (cosine < -TINY_COS_VALUE) + cosine = -TINY_COS_VALUE; + phi = acos(-cosine); sinphi = sin(phi); - if ( sinphi < TINY_SIN_VALUE ) sinphi = TINY_SIN_VALUE; - fac *= (phi - iaparams->p.angle_harmonic.phi0)/sinphi; + if (sinphi < TINY_SIN_VALUE) + sinphi = TINY_SIN_VALUE; + fac *= (phi - iaparams->p.angle_harmonic.phi0) / sinphi; } - for(j=0;j<3;j++) { + for (j = 0; j < 3; j++) { double f1 = fac * (cosine * vec1[j] - vec2[j]) * d1i; double f2 = fac * (cosine * vec2[j] - vec1[j]) * d2i; - force1[j] = (f1-f2); + force1[j] = (f1 - f2); force2[j] = -f1; } @@ -98,8 +104,10 @@ inline int calc_angle_harmonic_force(Particle *p_mid, Particle *p_left, Particle /* The force on each particle due to a three-body bonded potential is computed. */ inline void calc_angle_harmonic_3body_forces(Particle *p_mid, Particle *p_left, - Particle *p_right, Bonded_ia_parameters *iaparams, - double force1[3], double force2[3], double force3[3]) { + Particle *p_right, + Bonded_ia_parameters *iaparams, + double force1[3], double force2[3], + double force3[3]) { int j; double pot_dep; @@ -117,7 +125,7 @@ inline void calc_angle_harmonic_3body_forces(Particle *p_mid, Particle *p_left, double fac; get_mi_vector(vec12, p_mid->r.p, p_left->r.p); - for(j = 0; j < 3; j++) + for (j = 0; j < 3; j++) vec21[j] = -vec12[j]; get_mi_vector(vec31, p_right->r.p, p_mid->r.p); @@ -128,15 +136,17 @@ inline void calc_angle_harmonic_3body_forces(Particle *p_mid, Particle *p_left, cos_phi = scalar(vec21, vec31) / (vec21_magn * vec31_magn); sin_phi = sqrt(1.0 - Utils::sqr(cos_phi)); - /* uncomment this block if interested in the angle + /* uncomment this block if interested in the angle if(cos_phi < -1.0) cos_phi = -TINY_COS_VALUE; - if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; + if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; phi = acos(cos_phi); */ { double K, phi, phi0; - if(cos_phi < -1.0) cos_phi = -TINY_COS_VALUE; - if(cos_phi > 1.0) cos_phi = TINY_COS_VALUE; + if (cos_phi < -1.0) + cos_phi = -TINY_COS_VALUE; + if (cos_phi > 1.0) + cos_phi = TINY_COS_VALUE; phi = acos(cos_phi); K = iaparams->p.angle_harmonic.bend; @@ -148,21 +158,22 @@ inline void calc_angle_harmonic_3body_forces(Particle *p_mid, Particle *p_left, fac = pot_dep / sin_phi; - for(j = 0; j < 3; j++) { - fj[j] = vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; - fk[j] = vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; + for (j = 0; j < 3; j++) { + fj[j] = + vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr; + fk[j] = + vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr; } // note that F1 = -(F2 + F3) - for(j = 0; j < 3; j++) { + for (j = 0; j < 3; j++) { force1[j] = force1[j] - fac * (fj[j] + fk[j]); force2[j] = force2[j] + fac * fj[j]; force3[j] = force3[j] + fac * fk[j]; } } - -/** Computes the three body angle interaction energy. +/** Computes the three body angle interaction energy. @param p_mid Pointer to first particle. @param p_left Pointer to second/middle particle. @param p_right Pointer to third particle. @@ -170,32 +181,38 @@ inline void calc_angle_harmonic_3body_forces(Particle *p_mid, Particle *p_left, @param _energy return energy pointer. @return 0. */ -inline int angle_harmonic_energy(Particle *p_mid, Particle *p_left, Particle *p_right, - Bonded_ia_parameters *iaparams, double *_energy) -{ - double cosine, vec1[3], vec2[3], d1i, d2i, dist2; +inline int angle_harmonic_energy(Particle *p_mid, Particle *p_left, + Particle *p_right, + Bonded_ia_parameters *iaparams, + double *_energy) { + double cosine, vec1[3], vec2[3], d1i, d2i, dist2; int j; - cosine=0.0; + cosine = 0.0; /* vector from p_mid to p_left */ get_mi_vector(vec1, p_mid->r.p, p_left->r.p); dist2 = sqrlen(vec1); d1i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec1[j] *= d1i; + for (j = 0; j < 3; j++) + vec1[j] *= d1i; /* vector from p_right to p_mid */ get_mi_vector(vec2, p_right->r.p, p_mid->r.p); dist2 = sqrlen(vec2); d2i = 1.0 / sqrt(dist2); - for(j=0;j<3;j++) vec2[j] *= d2i; + for (j = 0; j < 3; j++) + vec2[j] *= d2i; /* scalar produvt of vec1 and vec2 */ cosine = scalar(vec1, vec2); - if ( cosine > TINY_COS_VALUE) cosine = TINY_COS_VALUE; - if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE; + if (cosine > TINY_COS_VALUE) + cosine = TINY_COS_VALUE; + if (cosine < -TINY_COS_VALUE) + cosine = -TINY_COS_VALUE; /* bond angle energy */ { double phi; - phi = acos(-cosine); - *_energy = 0.5*iaparams->p.angle_harmonic.bend*Utils::sqr(phi - iaparams->p.angle_harmonic.phi0); + phi = acos(-cosine); + *_energy = 0.5 * iaparams->p.angle_harmonic.bend * + Utils::sqr(phi - iaparams->p.angle_harmonic.phi0); } return 0; } diff --git a/src/core/angledist.cpp b/src/core/angledist.cpp index 4c7af63156..52ad5959d9 100755 --- a/src/core/angledist.cpp +++ b/src/core/angledist.cpp @@ -32,8 +32,8 @@ #include "constraints.hpp" #include "constraints/ShapeBasedConstraint.hpp" #include "grid.hpp" -#include #include "shapes/Wall.hpp" +#include int angledist_set_params(int bond_type, double bend, double phimin, double distmin, double phimax, double distmax) { @@ -82,16 +82,18 @@ static double calc_angledist_param(Particle *p_mid, Particle *p_left, const double distmx = iaparams->p.angledist.distmax; /* folds coordinates of p_mid into original box */ - Vector3d folded_pos =folded_position(*p_mid); + Vector3d folded_pos = folded_position(*p_mid); double pwdistmin = std::numeric_limits::infinity(); double pwdistmin_d = 0.0; for (auto const &c : Constraints::constraints) { - auto cs = std::dynamic_pointer_cast(c); + auto cs = + std::dynamic_pointer_cast(c); if (cs) { - if (dynamic_cast(&(cs->shape()))) { - const Shapes::Wall* wall = dynamic_cast(&(cs->shape())); + if (dynamic_cast(&(cs->shape()))) { + const Shapes::Wall *wall = + dynamic_cast(&(cs->shape())); double dist = -wall->d(); for (int j = 0; j < 3; j++) { dist += folded_pos[j] * (wall->n())[j]; diff --git a/src/core/bmhtf-nacl.cpp b/src/core/bmhtf-nacl.cpp index 7205630750..393132dba1 100755 --- a/src/core/bmhtf-nacl.cpp +++ b/src/core/bmhtf-nacl.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file bmhtf-nacl.cpp * @@ -27,27 +27,26 @@ #ifdef BMHTF_NACL #include "communication.hpp" -int BMHTF_set_params(int part_type_a, int part_type_b, - double A, double B, double C, - double D, double sig, double cut) -{ +int BMHTF_set_params(int part_type_a, int part_type_b, double A, double B, + double C, double D, double sig, double cut) { double shift, dist2, pw6; IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; - dist2 = cut*cut; - pw6 = dist2*dist2*dist2; - shift = -(A*exp(B*(sig - cut)) - C/pw6 - D/pw6/dist2); + dist2 = cut * cut; + pw6 = dist2 * dist2 * dist2; + shift = -(A * exp(B * (sig - cut)) - C / pw6 - D / pw6 / dist2); - data->BMHTF_A = A; - data->BMHTF_B = B; - data->BMHTF_C = C; - data->BMHTF_D = D; + data->BMHTF_A = A; + data->BMHTF_B = B; + data->BMHTF_C = C; + data->BMHTF_D = D; data->BMHTF_sig = sig; data->BMHTF_cut = cut; data->BMHTF_computed_shift = shift; - + /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); diff --git a/src/core/bmhtf-nacl.hpp b/src/core/bmhtf-nacl.hpp index fac51490ce..5a30832905 100755 --- a/src/core/bmhtf-nacl.hpp +++ b/src/core/bmhtf-nacl.hpp @@ -26,9 +26,9 @@ * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef BMHTF_NACL @@ -43,9 +43,10 @@ inline void add_BMHTF_pair_force(const Particle *const p1, double dist, double dist2, double force[3]) { if ((dist < ia_params->BMHTF_cut)) { double pw8 = dist2 * dist2 * dist2 * dist2; - double fac = ia_params->BMHTF_A * ia_params->BMHTF_B * - exp(ia_params->BMHTF_B * (ia_params->BMHTF_sig - dist)) / dist - - 6 * ia_params->BMHTF_C / pw8 - 8 * ia_params->BMHTF_D / pw8 / dist2; + double fac = + ia_params->BMHTF_A * ia_params->BMHTF_B * + exp(ia_params->BMHTF_B * (ia_params->BMHTF_sig - dist)) / dist - + 6 * ia_params->BMHTF_C / pw8 - 8 * ia_params->BMHTF_D / pw8 / dist2; for (int j = 0; j < 3; j++) force[j] += fac * d[j]; diff --git a/src/core/bonded_coulomb.cpp b/src/core/bonded_coulomb.cpp index fd4f339a1e..803a879114 100644 --- a/src/core/bonded_coulomb.cpp +++ b/src/core/bonded_coulomb.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file bonded_coulomb.cpp * @@ -27,19 +27,18 @@ #ifdef ELECTROSTATICS -int bonded_coulomb_set_params(int bond_type, double prefactor) -{ - if(bond_type < 0) +int bonded_coulomb_set_params(int bond_type, double prefactor) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); bonded_ia_params[bond_type].p.bonded_coulomb.prefactor = prefactor; bonded_ia_params[bond_type].type = BONDED_IA_BONDED_COULOMB; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/bonded_coulomb.hpp b/src/core/bonded_coulomb.hpp index 61693ee1d1..90578b2f39 100644 --- a/src/core/bonded_coulomb.hpp +++ b/src/core/bonded_coulomb.hpp @@ -1,27 +1,27 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _BONDED_COULOMB_HPP #define _BONDED_COULOMB_HPP /** \file bonded_coulomb.hpp - * Routines to calculate the BONDED_COULOMB Energy or/and BONDED_COULOMB force + * Routines to calculate the BONDED_COULOMB Energy or/and BONDED_COULOMB force * for a particle pair. * \ref forces.cpp */ @@ -32,42 +32,54 @@ #ifdef ELECTROSTATICS -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" /// set the parameters for the bonded_coulomb potential int bonded_coulomb_set_params(int bond_type, double prefactor); /** Computes the BONDED_COULOMB pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. - @param iaparams bond type number of the angle interaction (see \ref interaction_data.cpp). + @param iaparams bond type number of the angle interaction (see \ref + interaction_data.cpp). @param dx particle distance vector @param force returns force of particle 1 @return 0. */ -inline int calc_bonded_coulomb_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force[3]) -{ +inline int calc_bonded_coulomb_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double force[3]) { int i; double fac; double dist2 = sqrlen(dx); double dist = sqrt(dist2); - fac = iaparams->p.bonded_coulomb.prefactor * p1->p.q * p2->p.q / (dist*dist2); + fac = + iaparams->p.bonded_coulomb.prefactor * p1->p.q * p2->p.q / (dist * dist2); - for(i=0;i<3;i++) - force[i] = fac*dx[i]; - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: BONDED_COULOMB f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist2,fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: BONDED_COULOMB f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist2,fac)); + for (i = 0; i < 3; i++) + force[i] = fac * dx[i]; + ONEPART_TRACE(if (p1->p.identity == check_id) fprintf( + stderr, "%d: OPT: BONDED_COULOMB f = (%.3e,%.3e,%.3e) with part id=%d at " + "dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], p2->p.identity, dist2, + fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) fprintf( + stderr, "%d: OPT: BONDED_COULOMB f = (%.3e,%.3e,%.3e) with part id=%d at " + "dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], p1->p.identity, dist2, + fac)); return 0; } -inline int bonded_coulomb_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ +inline int bonded_coulomb_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double *_energy) { double dist = sqrt(sqrlen(dx)); *_energy = iaparams->p.bonded_coulomb.prefactor * p1->p.q * p2->p.q / dist; diff --git a/src/core/bonded_coulomb_p3m_sr.cpp b/src/core/bonded_coulomb_p3m_sr.cpp index f993ee6c84..70a0671ff2 100644 --- a/src/core/bonded_coulomb_p3m_sr.cpp +++ b/src/core/bonded_coulomb_p3m_sr.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file bonded_coulomb.cpp * @@ -27,19 +27,18 @@ #ifdef ELECTROSTATICS -int bonded_coulomb_p3m_sr_set_params(int bond_type, double q1q2) -{ - if(bond_type < 0) +int bonded_coulomb_p3m_sr_set_params(int bond_type, double q1q2) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); bonded_ia_params[bond_type].p.bonded_coulomb_p3m_sr.q1q2 = q1q2; bonded_ia_params[bond_type].type = BONDED_IA_BONDED_COULOMB_P3M_SR; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/bonded_coulomb_p3m_sr.hpp b/src/core/bonded_coulomb_p3m_sr.hpp index df43cc7c58..131fd25908 100644 --- a/src/core/bonded_coulomb_p3m_sr.hpp +++ b/src/core/bonded_coulomb_p3m_sr.hpp @@ -1,29 +1,31 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _BONDED_COULOMB_P3M_SR_HPP #define _BONDED_COULOMB_P3M_SR_HPP /** \file bonded_coulomb.hpp - * Routines to calculate the BONDED_COULOMB_P3M_SR Energy or/and BONDED_COULOMB_P3M_SR force - * for a particle pair. This is only the shortrange part of P3M and first - * used to subtract certain intramolecular interactions in combination with thole damping + * Routines to calculate the BONDED_COULOMB_P3M_SR Energy or/and + * BONDED_COULOMB_P3M_SR force + * for a particle pair. This is only the shortrange part of P3M and first + * used to subtract certain intramolecular interactions in combination with + * thole damping * \ref forces.cpp */ @@ -33,17 +35,17 @@ #ifdef P3M -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" -#include "particle_data.hpp" #include "p3m.hpp" +#include "particle_data.hpp" +#include "utils.hpp" /// set the parameters for the bonded_coulomb potential int bonded_coulomb_p3m_sr_set_params(int bond_type, double q1q2); /** Computes the BONDED_COULOMB_P3M_SR pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. @param iaparams bond parameters. @@ -51,25 +53,35 @@ int bonded_coulomb_p3m_sr_set_params(int bond_type, double q1q2); @param force returns force of particle 1 @return 0. */ -inline int calc_bonded_coulomb_p3m_sr_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force[3]) -{ +inline int calc_bonded_coulomb_p3m_sr_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], + double force[3]) { double dist2 = sqrlen(dx); double dist = sqrt(dist2); if (dist < p3m.params.r_cut) { - //Set to zero because p3m adds forces - force[0] = force[1] = force[2] = 0.; + // Set to zero because p3m adds forces + force[0] = force[1] = force[2] = 0.; + + p3m_add_pair_force(iaparams->p.bonded_coulomb_p3m_sr.q1q2, dx, dist2, dist, + force); - p3m_add_pair_force(iaparams->p.bonded_coulomb_p3m_sr.q1q2, dx, dist2, dist, force); - - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: BONDED_COULOMB_P3M_SR f = (%.3e,%.3e,%.3e) with part id=%d at dist %f\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist2)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: BONDED_COULOMB_P3M_SR f = (%.3e,%.3e,%.3e) with part id=%d at dist %f\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist2)); - } + ONEPART_TRACE(if (p1->p.identity == check_id) fprintf( + stderr, "%d: OPT: BONDED_COULOMB_P3M_SR f = (%.3e,%.3e,%.3e) with part " + "id=%d at dist %f\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], p2->p.identity, dist2)); + ONEPART_TRACE(if (p2->p.identity == check_id) fprintf( + stderr, "%d: OPT: BONDED_COULOMB_P3M_SR f = (%.3e,%.3e,%.3e) with part " + "id=%d at dist %f\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], p1->p.identity, dist2)); + } return 0; } -inline int bonded_coulomb_p3m_sr_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ +inline int bonded_coulomb_p3m_sr_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double *_energy) { double dist2 = sqrlen(dx); double dist = sqrt(dist2); *_energy = p3m_pair_energy(iaparams->p.bonded_coulomb_p3m_sr.q1q2, dist); diff --git a/src/core/buckingham.cpp b/src/core/buckingham.cpp index a12cc506d0..6fa4368c15 100755 --- a/src/core/buckingham.cpp +++ b/src/core/buckingham.cpp @@ -27,10 +27,9 @@ #ifdef BUCKINGHAM #include "communication.hpp" -int buckingham_set_params(int part_type_a, int part_type_b, - double A, double B, double C, double D, double cut, - double discont, double shift) -{ +int buckingham_set_params(int part_type_a, int part_type_b, double A, double B, + double C, double D, double cut, double discont, + double shift) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); if (!data) diff --git a/src/core/cells.hpp b/src/core/cells.hpp index d6349fbd62..bbb68cfc90 100755 --- a/src/core/cells.hpp +++ b/src/core/cells.hpp @@ -95,7 +95,11 @@ #define CELL_NEIGHBOR_EXCHANGE 0 namespace Cells { -enum Resort : unsigned { RESORT_NONE = 0u, RESORT_LOCAL = 1u, RESORT_GLOBAL = 2u }; +enum Resort : unsigned { + RESORT_NONE = 0u, + RESORT_LOCAL = 1u, + RESORT_GLOBAL = 2u +}; } /** \name Flags for cells_on_geometry_change */ @@ -290,7 +294,7 @@ std::vector> mpi_get_pairs(double distance); * * The changed level has to be commuicated via annouce_resort_particles. */ - void set_resort_particles(Cells::Resort level); +void set_resort_particles(Cells::Resort level); /** * @brief Get the currently scheduled resort level. diff --git a/src/core/cluster_analysis/Cluster.cpp b/src/core/cluster_analysis/Cluster.cpp index 66c0a00551..42954e0d47 100644 --- a/src/core/cluster_analysis/Cluster.cpp +++ b/src/core/cluster_analysis/Cluster.cpp @@ -1,92 +1,91 @@ -#include "particle_data.hpp" -#include "partCfg_global.hpp" #include "grid.hpp" +#include "partCfg_global.hpp" +#include "particle_data.hpp" #ifdef GSL - #include "gsl/gsl_fit.h" +#include "gsl/gsl_fit.h" #endif #include "Vector.hpp" #include -#include "Cluster.hpp" +#include "Cluster.hpp" namespace ClusterAnalysis { -//Center of mass of an aggregate -Vector3d Cluster::center_of_mass() -{ +// Center of mass of an aggregate +Vector3d Cluster::center_of_mass() { return center_of_mass_subcluster(particles); } +// Center of mass of an aggregate +Vector3d +Cluster::center_of_mass_subcluster(std::vector &subcl_partcicle_ids) { + Vector3d com{}; -//Center of mass of an aggregate -Vector3d Cluster::center_of_mass_subcluster(std::vector &subcl_partcicle_ids) -{ - Vector3d com{}; - // The distances between the particles "folded", such that all distances // are smaller than box_l/2 in a periodic system. The 1st particle // of the cluster is arbitrarily chosen as reference. - - Vector3d reference_position=folded_position(partCfg()[particles[0]]); + + Vector3d reference_position = folded_position(partCfg()[particles[0]]); Vector3d dist_to_reference; - double total_mass=0.; - for (int pid : subcl_partcicle_ids) //iterate over all particle ids within a cluster + double total_mass = 0.; + for (int pid : + subcl_partcicle_ids) // iterate over all particle ids within a cluster { - const Vector3d folded_pos=folded_position(partCfg()[pid]); - get_mi_vector(dist_to_reference, folded_pos, reference_position); //add current particle positions - com = com + dist_to_reference *partCfg()[pid].p.mass; + const Vector3d folded_pos = folded_position(partCfg()[pid]); + get_mi_vector(dist_to_reference, folded_pos, + reference_position); // add current particle positions + com = com + dist_to_reference * partCfg()[pid].p.mass; total_mass += partCfg()[pid].p.mass; } // Normalize by numer of particles - com = com * 1./total_mass; + com = com * 1. / total_mass; // Re-add reference position - com = com +reference_position; + com = com + reference_position; // Fold into simulation box - - for (int i = 0; i < 3; i ++) { - com[i] = fmod(com[i],box_l[i]); + + for (int i = 0; i < 3; i++) { + com[i] = fmod(com[i], box_l[i]); } return com; } double Cluster::longest_distance() { - double ld=0.; - for (auto a=particles.begin();a!=particles.end();a++) { - for (auto b=a;++b!=particles.end();) { + double ld = 0.; + for (auto a = particles.begin(); a != particles.end(); a++) { + for (auto b = a; ++b != particles.end();) { double dist[3]; - get_mi_vector(dist, partCfg()[*a].r.p,partCfg()[*b].r.p); - + get_mi_vector(dist, partCfg()[*a].r.p, partCfg()[*b].r.p); + // Larger than previous largest distance? if (ld < sqrt(sqrlen(dist))) { - ld=sqrt(sqrlen(dist)); //save bigger value as longest distance - ld + ld = sqrt(sqrlen(dist)); // save bigger value as longest distance - ld } } } return ld; } - -//Radius of gyration +// Radius of gyration double Cluster::radius_of_gyration() { return radius_of_gyration_subcluster(particles); } - -double Cluster::radius_of_gyration_subcluster(std::vector &subcl_particle_ids) { +double +Cluster::radius_of_gyration_subcluster(std::vector &subcl_particle_ids) { // Center of mass - Vector3d com=center_of_mass_subcluster(subcl_particle_ids); - double sum_sq_dist=0.; + Vector3d com = center_of_mass_subcluster(subcl_particle_ids); + double sum_sq_dist = 0.; for (auto const pid : subcl_particle_ids) { double distance[3]; get_mi_vector(distance, com, partCfg()[pid].r.p); -// calculate square length of this distance + // calculate square length of this distance sum_sq_dist += sqrlen(distance); - } - - return sqrt(sum_sq_dist/subcl_particle_ids.size()); + } + + return sqrt(sum_sq_dist / subcl_particle_ids.size()); } template @@ -98,60 +97,64 @@ std::vector sort_indices(const std::vector &v) { // sort indices based on comparing values in v std::sort(idx.begin(), idx.end(), - [&v](std::size_t i1, std::size_t i2) {return v[i1] < v[i2];}); + [&v](std::size_t i1, std::size_t i2) { return v[i1] < v[i2]; }); return idx; } - -std::pair Cluster::fractal_dimension(double dr) { +std::pair Cluster::fractal_dimension(double dr) { #ifdef GSL - Vector3d com = center_of_mass(); -// calculate Df using linear regression on the logarithms of the radii of gyration against the number of particles in sub-clusters. Particles are included step by step from the center of mass outwards + Vector3d com = center_of_mass(); + // calculate Df using linear regression on the logarithms of the radii of + // gyration against the number of particles in sub-clusters. Particles are + // included step by step from the center of mass outwards // Distnaces of particles from the center of mass std::vector distances; - - for (auto const& it : particles) { + for (auto const &it : particles) { double dist[3]; - get_mi_vector(dist, com.begin(), partCfg()[it].r.p); - distances.push_back(sqrt(sqrlen(dist))); //add distance from the current particle to the com in the distances vectors + get_mi_vector(dist, com.begin(), partCfg()[it].r.p); + distances.push_back(sqrt(sqrlen(dist))); // add distance from the current + // particle to the com in the + // distances vectors } - - // Get particle indices in the cluster which yield distances sorted in ascending order from center of mass. - auto particle_indices=sort_indices(distances); - + // Get particle indices in the cluster which yield distances sorted in + // ascending order from center of mass. + auto particle_indices = sort_indices(distances); // Particle ids in the current sub-cluster std::vector subcluster_ids; - - std::vector log_pcounts; // particle count + + std::vector log_pcounts; // particle count std::vector log_diameters; // corresponding radii of gyration - double last_dist=0; + double last_dist = 0; for (auto const idx : particle_indices) { subcluster_ids.push_back(particles[idx]); - if (distances[idx] -#include #include "Vector.hpp" #include #include +#include +#include #include "interaction_data.hpp" #include "particle_data.hpp" #include - namespace ClusterAnalysis { /** @brief Represents a single cluster of particles */ /** @brief Represents a single cluster of particles */ class Cluster { - public: - /** @brief Ids of the particles in the cluster */ - std::vector particles; - /** @brief add a particle to the cluster */ - void add_particle(const Particle& p) { - particles.push_back(p.p.identity); - } - /** @brief Calculate the center of mass of the cluster */ - Vector3d center_of_mass_subcluster(std::vector &subcl_partcicle_ids); - Vector3d center_of_mass(); - /** @brief Longest distance between any combination of two particles */ - double longest_distance(); - /** @brief Calculate radius of gyration of the cluster */ - double radius_of_gyration(); - double radius_of_gyration_subcluster(std::vector &subcl_particle_ids); - /** @brief Calculate the fractal dimension - * N(r) via r^d, where N(r) counts the number of particles in a sphere - * of radius n, and d denotes the fractal dimension. - * The fitting is done by the Gnu Scientific Library. - * @param dr: increment for when constructing the discrete version of N(r) - * @param mean_sq_residual: Mean square residual returned by the fit - * - * @return fractal dimension, rms error of the fit */ - std::pair fractal_dimension(double dr); +public: + /** @brief Ids of the particles in the cluster */ + std::vector particles; + /** @brief add a particle to the cluster */ + void add_particle(const Particle &p) { particles.push_back(p.p.identity); } + /** @brief Calculate the center of mass of the cluster */ + Vector3d center_of_mass_subcluster(std::vector &subcl_partcicle_ids); + Vector3d center_of_mass(); + /** @brief Longest distance between any combination of two particles */ + double longest_distance(); + /** @brief Calculate radius of gyration of the cluster */ + double radius_of_gyration(); + double radius_of_gyration_subcluster(std::vector &subcl_particle_ids); + /** @brief Calculate the fractal dimension + * N(r) via r^d, where N(r) counts the number of particles in a sphere + * of radius n, and d denotes the fractal dimension. + * The fitting is done by the Gnu Scientific Library. + * @param dr: increment for when constructing the discrete version of N(r) + * @param mean_sq_residual: Mean square residual returned by the fit + * + * @return fractal dimension, rms error of the fit */ + std::pair fractal_dimension(double dr); }; - } // namespace ClusterAnalysis - - #endif - diff --git a/src/core/cluster_analysis/ClusterStructure.cpp b/src/core/cluster_analysis/ClusterStructure.cpp index 893611f1db..ad66f4a4bc 100644 --- a/src/core/cluster_analysis/ClusterStructure.cpp +++ b/src/core/cluster_analysis/ClusterStructure.cpp @@ -1,121 +1,107 @@ #include "Cluster.hpp" #include "ClusterStructure.hpp" #include "interaction_data.hpp" +#include "partCfg_global.hpp" +#include "utils/for_each_pair.hpp" #include #include -#include "partCfg_global.hpp" -#include "utils/for_each_pair.hpp" namespace ClusterAnalysis { - -ClusterStructure::ClusterStructure() { - clear(); -} +ClusterStructure::ClusterStructure() { clear(); } void ClusterStructure::clear() { - clusters.clear(); - cluster_id.clear(); - m_cluster_identities.clear(); + clusters.clear(); + cluster_id.clear(); + m_cluster_identities.clear(); } -inline bool ClusterStructure::part_of_cluster(const Particle& p) -{ - if (cluster_id.find(p.p.identity)==cluster_id.end()) return false; - return true; +inline bool ClusterStructure::part_of_cluster(const Particle &p) { + if (cluster_id.find(p.p.identity) == cluster_id.end()) + return false; + return true; } // Analyze the cluster structure of the given particles -void ClusterStructure::run_for_all_pairs() -{ +void ClusterStructure::run_for_all_pairs() { // clear data structs clear(); - + // Iterate over pairs - Utils::for_each_pair(partCfg().begin(),partCfg().end(), - [this](const Particle& p1, const Particle& p2) {this->add_pair(p1,p2);}); + Utils::for_each_pair(partCfg().begin(), partCfg().end(), + [this](const Particle &p1, const Particle &p2) { + this->add_pair(p1, p2); + }); merge_clusters(); } void ClusterStructure::run_for_bonded_particles() { -clear(); -partCfg().update_bonds(); -for (auto p : partCfg()) { - int j=0; - while (jdecide(p1,p2)) { - - if // None belongs to a cluster - ((!part_of_cluster(p1)) && (!part_of_cluster(p2))) - { - // Both particles belong to the same, new cluster - const int cid=get_next_free_cluster_id(); + if (m_pair_criterion->decide(p1, p2)) { - // assign the cluster_ids - cluster_id[p1.p.identity]=cid; - cluster_id[p2.p.identity]=cid; - } - else if // p2 belongs to a cluster but p1 doesn't - (part_of_cluster(p2) && !part_of_cluster(p1)) - { - // Give p1 the same cluster id as p2 - cluster_id[p1.p.identity]=find_id_for(cluster_id.at(p2.p.identity)); - } - else if // i belongs to a cluster but j doesn't - (part_of_cluster(p1) && !part_of_cluster(p2)) - { - // give p2 the cluster id from p1 - cluster_id[p2.p.identity]=find_id_for(cluster_id.at(p1.p.identity)); - } - else if // Both belong to different clusters - (part_of_cluster(p1) && part_of_cluster(p2) && - cluster_id.at(p1.p.identity)!=cluster_id.at(p2.p.identity)) - { - // Clusters of p1 and p2 are one and the same. Add an identity to the list - // The higher number must be inserted as first value of tjhe pair - // because the substituions later have to be done in descending order - const int cid1=find_id_for(cluster_id.at(p1.p.identity)); - const int cid2=find_id_for(cluster_id.at(p2.p.identity)); - if (cid1>cid2) - { - m_cluster_identities[cid1] =cid2; - } - else if (cid1 cid2) { + m_cluster_identities[cid1] = cid2; + } else if (cid1 < cid2) { + m_cluster_identities[cid2] = cid1; + } + // else do nothing. The clusters are already noted for merging. + // Connected clusters will be merged later } // The case for both particles being in the same cluster does not need to be // treated. @@ -125,36 +111,37 @@ void ClusterStructure::add_pair(const Particle& p1, const Particle& p2) { void ClusterStructure::merge_clusters() { // Relabel particles according to the cluster identities map // Also create empty cluster objects for the final cluster id - + // Collect needed changes in a separate map, as doing the changes on the fly // would screw up the iterators - std::vector> to_be_changed; - - for (auto it : cluster_id) { + std::vector> to_be_changed; + + for (auto it : cluster_id) { // particle id is in it.first and cluster id in it.second // We change the cluster id according to the cluster identities // map - const int cid=find_id_for(it.second); + const int cid = find_id_for(it.second); // We note the list of changes here, so we don't modify the map // while iterating - to_be_changed.push_back({it.first,cid}); + to_be_changed.push_back({it.first, cid}); // Empty cluster object - if (clusters.find(cid)==clusters.end()) { - clusters[cid]=std::make_shared(); + if (clusters.find(cid) == clusters.end()) { + clusters[cid] = std::make_shared(); } } - + // Now act on the changes marke in above iteration for (auto it : to_be_changed) { - cluster_id[it.first]=it.second; + cluster_id[it.first] = it.second; } - + // Now fill the cluster objects with particle ids - // Iterate over particles, fill in the cluster map - // to each cluster particle the corresponding cluster id + // Iterate over particles, fill in the cluster map + // to each cluster particle the corresponding cluster id for (auto it : cluster_id) { - // If this is the first particle in this cluster, instance a new cluster object - if (clusters.find(it.second)==clusters.end()){ + // If this is the first particle in this cluster, instance a new cluster + // object + if (clusters.find(it.second) == clusters.end()) { clusters[it.second] = std::make_shared(); } clusters[it.second]->particles.push_back(it.first); @@ -162,37 +149,27 @@ void ClusterStructure::merge_clusters() { // Sort particles ids in the cluters for (auto c : clusters) { - std::sort(c.second->particles.begin(),c.second->particles.end()); + std::sort(c.second->particles.begin(), c.second->particles.end()); } } - -int ClusterStructure::find_id_for(int x) -{ - int tmp=x; - while (m_cluster_identities.find(tmp)!=m_cluster_identities.end()) - { - tmp =m_cluster_identities[tmp]; - } - return tmp; +int ClusterStructure::find_id_for(int x) { + int tmp = x; + while (m_cluster_identities.find(tmp) != m_cluster_identities.end()) { + tmp = m_cluster_identities[tmp]; + } + return tmp; } -int ClusterStructure::get_next_free_cluster_id(){ - //iterate over cluster_id' +int ClusterStructure::get_next_free_cluster_id() { + // iterate over cluster_id' int max_seen_cluster = 0; - for (auto it : cluster_id){ - int cid=it.second; - if (max_seen_cluster < cid ) { - max_seen_cluster=cid; + for (auto it : cluster_id) { + int cid = it.second; + if (max_seen_cluster < cid) { + max_seen_cluster = cid; } } - return max_seen_cluster+1; + return max_seen_cluster + 1; } - - - } - - - - diff --git a/src/core/cluster_analysis/ClusterStructure.hpp b/src/core/cluster_analysis/ClusterStructure.hpp index d9a88900df..35370fc4b8 100644 --- a/src/core/cluster_analysis/ClusterStructure.hpp +++ b/src/core/cluster_analysis/ClusterStructure.hpp @@ -2,55 +2,59 @@ #ifndef CLUSTER_ANALYSIS_CLUSTER_STRUCTURE_HPP #define CLUSTER_ANALYSIS_CLUSTER_STRUCTURE_HPP - -#include +#include "pair_criteria/pair_criteria.hpp" #include #include -#include "pair_criteria/pair_criteria.hpp" +#include -#include "pair_criteria/pair_criteria.hpp" +#include "Cluster.hpp" #include "interaction_data.hpp" +#include "pair_criteria/pair_criteria.hpp" #include "particle_data.hpp" -#include "Cluster.hpp" namespace ClusterAnalysis { - /** @brief Represents a single cluster of particles */ /** @brief Holds the result and parameters of a cluster analysis */ class ClusterStructure { - public: +public: ClusterStructure(); - /** @brief Map holding the individual clusters. The key is an interger cluster id */ - std::map> clusters; + /** @brief Map holding the individual clusters. The key is an interger cluster + * id */ + std::map> clusters; /** @brief Map between particle ids and corresponding cluster ids */ std::map cluster_id; /** @brief Clear data strucutres */ void clear(); /** @brief Run cluster analysis, consider all aprticle pairs */ void run_for_all_pairs(); - /** @brief Run cluster analysis, consider pairs of particles connected by a bonded interaction */ + /** @brief Run cluster analysis, consider pairs of particles connected by a + * bonded interaction */ void run_for_bonded_particles(); /** Is particle p part of a cluster */ - bool part_of_cluster(const Particle& p); + bool part_of_cluster(const Particle &p); /** Sets the pair criterion which decides if two particles are neighbors */ - void set_pair_criterion(std::shared_ptr const &c) { + void + set_pair_criterion(std::shared_ptr const &c) { m_pair_criterion = c; } - PairCriteria::PairCriterion const &pair_criterion() const { return *m_pair_criterion; } + PairCriteria::PairCriterion const &pair_criterion() const { + return *m_pair_criterion; + } - private: +private: /** @brief Clusters that turn out to be the same during the analysis process - * (i.e., if two particles are neighbors that already belong to different clusters + * (i.e., if two particles are neighbors that already belong to different + * clusters */ - std::map m_cluster_identities; + std::map m_cluster_identities; /** @brief pari criterion which decides whether two particles are neighbors */ std::shared_ptr m_pair_criterion; - + /** @brief Consider an individual pair of particles during cluster analysis */ - void add_pair(const Particle& p1, const Particle& p2); + void add_pair(const Particle &p1, const Particle &p2); /** Merge clusters and populate their structures */ void merge_clusters(); /** @brief Follow a chain of cluster identities during analysis */ @@ -58,6 +62,5 @@ class ClusterStructure { /** @brief Get next free lucster id */ inline int get_next_free_cluster_id(); }; - } #endif diff --git a/src/core/collision.cpp b/src/core/collision.cpp index dee175232e..f3980d328d 100644 --- a/src/core/collision.cpp +++ b/src/core/collision.cpp @@ -21,13 +21,13 @@ #include "cells.hpp" #include "collision.hpp" +#include "collision.hpp" #include "communication.hpp" #include "errorhandling.hpp" #include "grid.hpp" -#include "particle_data.hpp" -#include "collision.hpp" #include "initialize.hpp" #include "interaction_data.hpp" +#include "particle_data.hpp" #include "rotation.hpp" #include "virtual_sites/VirtualSitesRelative.hpp" diff --git a/src/core/communication.cpp b/src/core/communication.cpp index 1ff37a09ba..feb0063815 100755 --- a/src/core/communication.cpp +++ b/src/core/communication.cpp @@ -392,13 +392,13 @@ void mpi_place_new_particle_slave(int pnode, int part) { } /****************** REQ_SET_V ************/ -void mpi_send_v(int pnode, int part, double* v) { +void mpi_send_v(int pnode, int part, double *v) { mpi_call(mpi_send_v_slave, pnode, part); if (pnode == this_node) { Particle *p = local_particles[part]; - p->m.v = {v[0],v[1],v[2]}; + p->m.v = {v[0], v[1], v[2]}; } else MPI_Send(v, 3, MPI_DOUBLE, pnode, SOME_TAG, comm_cart); @@ -408,7 +408,8 @@ void mpi_send_v(int pnode, int part, double* v) { void mpi_send_v_slave(int pnode, int part) { if (pnode == this_node) { Particle *p = local_particles[part]; - MPI_Recv(p->m.v.data(), 3, MPI_DOUBLE, 0, SOME_TAG, comm_cart, MPI_STATUS_IGNORE); + MPI_Recv(p->m.v.data(), 3, MPI_DOUBLE, 0, SOME_TAG, comm_cart, + MPI_STATUS_IGNORE); } on_particle_change(); @@ -1590,7 +1591,7 @@ void mpi_send_ext_torque(int pnode, int part, int flag, int mask, p->p.ext_flag |= flag; if (mask & PARTICLE_EXT_TORQUE) - p->p.ext_torque ={torque[0],torque[1],torque[2]}; + p->p.ext_torque = {torque[0], torque[1], torque[2]}; } else { int s_buf[2]; s_buf[0] = flag; @@ -1639,7 +1640,7 @@ void mpi_send_ext_force(int pnode, int part, int flag, int mask, /* set new values */ p->p.ext_flag |= flag; if (mask & PARTICLE_EXT_FORCE) - p->p.ext_force ={force[0],force[1],force[2]}; + p->p.ext_force = {force[0], force[1], force[2]}; } else { int s_buf[2]; s_buf[0] = flag; @@ -1864,7 +1865,9 @@ void mpi_send_exclusion_slave(int part1, int part2) { } /************** REQ_SET_FLUID **************/ -void mpi_send_fluid(int node, int index, double rho, const std::array &j, const std::array &pi) { +void mpi_send_fluid(int node, int index, double rho, + const std::array &j, + const std::array &pi) { #ifdef LB if (node == this_node) { lb_calc_n_from_rho_j_pi(index, rho, j, pi); @@ -1883,7 +1886,8 @@ void mpi_send_fluid_slave(int node, int index) { double data[10]; MPI_Recv(data, 10, MPI_DOUBLE, 0, SOME_TAG, comm_cart, MPI_STATUS_IGNORE); std::array j = {{data[1], data[2], data[3]}}; - std::array pi = {{data[4], data[5], data[6], data[7], data[8], data[9]}}; + std::array pi = { + {data[4], data[5], data[6], data[7], data[8], data[9]}}; lb_calc_n_from_rho_j_pi(index, data[0], j, pi); } #endif diff --git a/src/core/communication.hpp b/src/core/communication.hpp index cbd5514546..1f5c0b0bc7 100755 --- a/src/core/communication.hpp +++ b/src/core/communication.hpp @@ -125,8 +125,8 @@ void mpi_finalize(); * and node grid. */ void mpi_reshape_communicator(std::array const &node_grid, - std::array const &periodicity = {{1, 1, - 1}}); + std::array const &periodicity = { + {1, 1, 1}}); /** Issue REQ_EVENT: tells all clients of some system change. The events are: @@ -180,7 +180,7 @@ void mpi_send_swimming(int node, int part, ParticleParametersSwimming swim); \param node the node it is attached to. \param F its new force. */ -void mpi_send_f(int node, int part, const Vector3d & F); +void mpi_send_f(int node, int part, const Vector3d &F); /** issue req_set_solv: send particle solvation free energy also calls \ref on_particle_change. @@ -224,14 +224,14 @@ void mpi_send_mu_E(int node, int part, double mu_E[3]); void mpi_send_rotational_inertia(int node, int part, double rinertia[3]); #endif #ifdef ROTATION -/** Mpi call for rotating a single particle +/** Mpi call for rotating a single particle Also calls \ref on_particle_change. \param part the particle. \param node the node it is attached to. \param axis rotation axis \param angle rotation angle */ -void mpi_rotate_particle(int node, int part, double axis[3],double angle); +void mpi_rotate_particle(int node, int part, double axis[3], double angle); #endif #ifdef AFFINITY @@ -318,7 +318,7 @@ void mpi_send_virtual(int node, int part, int is_virtual); #ifdef VIRTUAL_SITES_RELATIVE void mpi_send_vs_quat(int node, int part, double *vs_quat); void mpi_send_vs_relative(int node, int part, int vs_relative_to, - double vs_distance, double* rel_ori); + double vs_distance, double *rel_ori); #endif /** Issue REQ_SET_TYPE: send particle type. @@ -542,7 +542,9 @@ void mpi_bcast_cuda_global_part_vars(); * @param j local fluid velocity * @param pi local fluid pressure */ -void mpi_send_fluid(int node, int index, double rho, const std::array &j, const std::array &pi); +void mpi_send_fluid(int node, int index, double rho, + const std::array &j, + const std::array &pi); /** Issue REQ_GET_FLUID: Receive a single lattice site from a processor. * @param node processor to send to diff --git a/src/core/constraints/HomogeneousMagneticField.cpp b/src/core/constraints/HomogeneousMagneticField.cpp index 24911beb8a..72f1978096 100644 --- a/src/core/constraints/HomogeneousMagneticField.cpp +++ b/src/core/constraints/HomogeneousMagneticField.cpp @@ -3,18 +3,20 @@ namespace Constraints { -ParticleForce HomogeneousMagneticField::force(const Particle &p, const Vector3d &folded_pos) { +ParticleForce HomogeneousMagneticField::force(const Particle &p, + const Vector3d &folded_pos) { #if defined(ROTATION) && defined(DIPOLES) - return {Vector3d{}, Vector3d::cross(p.r.dip, m_field)}; + return {Vector3d{}, Vector3d::cross(p.r.dip, m_field)}; #else - return {Vector3d{}}; + return {Vector3d{}}; #endif } -void HomogeneousMagneticField::add_energy(const Particle &p, const Vector3d &folded_pos, Observable_stat &energy) const { +void HomogeneousMagneticField::add_energy(const Particle &p, + const Vector3d &folded_pos, + Observable_stat &energy) const { #ifdef DIPOLES - energy.dipolar[0] += -1.0 * m_field * p.r.dip; + energy.dipolar[0] += -1.0 * m_field * p.r.dip; #endif } - } diff --git a/src/core/cos2.cpp b/src/core/cos2.cpp index d91dbe4215..361883658d 100644 --- a/src/core/cos2.cpp +++ b/src/core/cos2.cpp @@ -1,26 +1,26 @@ /* Copyright (C) 2010,2011,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file cos2.hpp - * Routines to calculate a flat potential with cosine tail energy and/or force + * Routines to calculate a flat potential with cosine tail energy and/or force * for a particle pair. Cosine tail is different from that in ljcos.hpp * Used for attractive tail/tail interactions in lipid bilayer calculations. * Same potential as ljcos2 without Lennard-Jones part. @@ -31,23 +31,22 @@ #ifdef COS2 #include -#include "lj.hpp" #include "communication.hpp" +#include "lj.hpp" -int cos2_set_params(int part_type_a, int part_type_b, - double eps, double offset, - double w) -{ +int cos2_set_params(int part_type_a, int part_type_b, double eps, double offset, + double w) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; - data->COS2_eps = eps; + data->COS2_eps = eps; data->COS2_offset = offset; - data->COS2_w = w; + data->COS2_w = w; /* calculate dependent parameters */ - data->COS2_cut = w + offset; + data->COS2_cut = w + offset; /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); @@ -55,5 +54,4 @@ int cos2_set_params(int part_type_a, int part_type_b, return ES_OK; } - #endif /* ifdef COS2 */ diff --git a/src/core/cos2.hpp b/src/core/cos2.hpp index a1f5592314..3997595e8d 100644 --- a/src/core/cos2.hpp +++ b/src/core/cos2.hpp @@ -1,68 +1,71 @@ /* Copyright (C) 2010,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _COS2_H #define _COS2_H /** \file cos2.hpp - * Routines to calculate a flat potential with cosine tail energy and/or force + * Routines to calculate a flat potential with cosine tail energy and/or force * for a particle pair. Cosine tail is different from that in ljcos.hpp * Used for attractive tail/tail interactions in lipid bilayer calculations. * Same potential as ljcos2 without Lennard-Jones part. * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef COS2 #include -int cos2_set_params(int part_type_a, int part_type_b, - double eps, double offset, double w); +int cos2_set_params(int part_type_a, int part_type_b, double eps, double offset, + double w); /** Calculate cos2 force between particle p1 and p2 */ -inline void add_cos2_pair_force(Particle *p1, Particle *p2, IA_parameters *ia_params, - double d[3], double dist, double force[3]) -{ - if((dist < ia_params->COS2_cut)) { +inline void add_cos2_pair_force(Particle *p1, Particle *p2, + IA_parameters *ia_params, double d[3], + double dist, double force[3]) { + if ((dist < ia_params->COS2_cut)) { double fac; if (dist > ia_params->COS2_offset) { - fac = -ia_params->COS2_eps*M_PI/2/ia_params->COS2_w/dist * sin(M_PI*(dist-ia_params->COS2_offset)/ia_params->COS2_w); + fac = -ia_params->COS2_eps * M_PI / 2 / ia_params->COS2_w / dist * + sin(M_PI * (dist - ia_params->COS2_offset) / ia_params->COS2_w); } - for(int j=0;j<3;j++) + for (int j = 0; j < 3; j++) force[j] += fac * d[j]; } } /** calculate cos2 energy between particle p1 and p2. */ -inline double cos2_pair_energy(Particle *p1, Particle *p2, IA_parameters *ia_params, - double d[3], double dist) -{ +inline double cos2_pair_energy(Particle *p1, Particle *p2, + IA_parameters *ia_params, double d[3], + double dist) { - if((dist < ia_params->COS2_cut)) { + if ((dist < ia_params->COS2_cut)) { if (dist < ia_params->COS2_offset) return -ia_params->COS2_eps; else - return -ia_params->COS2_eps/2 * (cos(M_PI*(dist-ia_params->COS2_offset)/ia_params->COS2_w)+1); + return -ia_params->COS2_eps / 2 * + (cos(M_PI * (dist - ia_params->COS2_offset) / ia_params->COS2_w) + + 1); } return 0.0; } diff --git a/src/core/cuda_init.cpp b/src/core/cuda_init.cpp index 93f430d47a..4fba623c1b 100644 --- a/src/core/cuda_init.cpp +++ b/src/core/cuda_init.cpp @@ -1,42 +1,43 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#include "config.hpp" -#include "utils.hpp" #include "cuda_init.hpp" #include "communication.hpp" +#include "config.hpp" +#include "utils.hpp" +#include #include -#include #include -#include +#include #ifdef CUDA -/** Helper class force device set +/** Helper class force device set */ struct CompareDevices { - bool operator()(const EspressoGpuDevice &a, const EspressoGpuDevice &b) const { + bool operator()(const EspressoGpuDevice &a, + const EspressoGpuDevice &b) const { const int name_comp = strncmp(a.proc_name, b.proc_name, 63); /* Both devs are from the same node, order by id */ - if(name_comp == 0) + if (name_comp == 0) return a.id < b.id; else return name_comp < 0; @@ -62,54 +63,57 @@ std::vector cuda_gather_gpus(void) { MPI_Get_processor_name(proc_name, &proc_name_len); /* Truncate to 63 chars to fit struct. */ - if(strlen(proc_name) > 63) + if (strlen(proc_name) > 63) proc_name[63] = 0; - for(int i = 0; i < n_gpus; ++i) { + for (int i = 0; i < n_gpus; ++i) { /* Check if device has at least mininum compute capability */ - if(cuda_check_gpu(i) == ES_OK) { + if (cuda_check_gpu(i) == ES_OK) { EspressoGpuDevice device; - if(cuda_get_device_props(i, device) == ES_OK){ - strncpy(device.proc_name, proc_name, 64); - devices.push_back(device); + if (cuda_get_device_props(i, device) == ES_OK) { + strncpy(device.proc_name, proc_name, 64); + devices.push_back(device); } } } - + /** Update n_gpus to number of usable devices */ n_gpus = devices.size(); - if(this_node == 0) { + if (this_node == 0) { std::set device_set; n_gpu_array = new int[n_nodes]; MPI_Gather(&n_gpus, 1, MPI_INT, n_gpu_array, 1, MPI_INT, 0, MPI_COMM_WORLD); /* insert local devices */ - std::copy(devices.begin(), devices.end(), std::inserter(device_set, device_set.begin())); + std::copy(devices.begin(), devices.end(), + std::inserter(device_set, device_set.begin())); - EspressoGpuDevice device; + EspressoGpuDevice device; MPI_Status s; /* Get devices from other nodes */ - for(int i = 1; i < n_nodes; ++i) { - for(int j = 0; j < n_gpu_array[i]; ++j) { - MPI_Recv(&device, sizeof(EspressoGpuDevice), MPI_BYTE, i, 0, MPI_COMM_WORLD, &s); - device_set.insert(device); - } + for (int i = 1; i < n_nodes; ++i) { + for (int j = 0; j < n_gpu_array[i]; ++j) { + MPI_Recv(&device, sizeof(EspressoGpuDevice), MPI_BYTE, i, 0, + MPI_COMM_WORLD, &s); + device_set.insert(device); + } } /* Copy unique devices to result, if any */ - std::copy(device_set.begin(), device_set.end(), std::inserter(g_devices, g_devices.begin())); + std::copy(device_set.begin(), device_set.end(), + std::inserter(g_devices, g_devices.begin())); delete[] n_gpu_array; } else { /* Send number of devices to master */ MPI_Gather(&n_gpus, 1, MPI_INT, n_gpu_array, 1, MPI_INT, 0, MPI_COMM_WORLD); /* Send devices to maser */ - for(std::vector::iterator device = devices.begin(); - device != devices.end(); ++device) { - MPI_Send(&(*device), sizeof(EspressoGpuDevice), MPI_BYTE, 0, 0, MPI_COMM_WORLD); + for (std::vector::iterator device = devices.begin(); + device != devices.end(); ++device) { + MPI_Send(&(*device), sizeof(EspressoGpuDevice), MPI_BYTE, 0, 0, + MPI_COMM_WORLD); } - } + } return g_devices; } #endif /* CUDA */ - diff --git a/src/core/cuda_init.hpp b/src/core/cuda_init.hpp index 04b5c376ee..14ae2bcf28 100755 --- a/src/core/cuda_init.hpp +++ b/src/core/cuda_init.hpp @@ -1,20 +1,20 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _CUDA_INIT_H #define _CUDA_INIT_H @@ -52,7 +52,7 @@ void cuda_init(); @return the number of GPUs, or -1 if CUDA could not be initialized. The error message from CUDA can be found in \ref - cuda_error. + cuda_error. */ int cuda_get_n_gpus(); @@ -96,13 +96,13 @@ int cuda_get_device(); int cuda_test_device_access(); -/** Gather unique list of CUDA devices on all nodes +/** Gather unique list of CUDA devices on all nodes @return vector of device on master, empty vector on other nodes. */ std::vector cuda_gather_gpus(void); -/** Get properties of a CUDA device +/** Get properties of a CUDA device */ int cuda_get_device_props(const int dev, EspressoGpuDevice &d); diff --git a/src/core/cuda_interface.cpp b/src/core/cuda_interface.cpp index e9d1c32bf2..d0d572ad8e 100644 --- a/src/core/cuda_interface.cpp +++ b/src/core/cuda_interface.cpp @@ -17,14 +17,10 @@ along with this program. If not, see . */ - #include "cuda_interface.hpp" #ifdef CUDA -#include "utils/serialization/CUDA_particle_data.hpp" -#include "utils/mpi/gather_buffer.hpp" -#include "utils/mpi/scatter_buffer.hpp" #include "communication.hpp" #include "config.hpp" #include "debug.hpp" @@ -32,7 +28,9 @@ #include "grid.hpp" #include "interaction_data.hpp" #include "random.hpp" - +#include "utils/mpi/gather_buffer.hpp" +#include "utils/mpi/scatter_buffer.hpp" +#include "utils/serialization/CUDA_particle_data.hpp" /// MPI tag for cuda particle gathering #define REQ_CUDAGETPARTS 0xcc01 @@ -266,9 +264,9 @@ on mpi.h. */ void copy_CUDA_energy_to_energy(CUDA_energy energy_host) { energy.bonded[0] += energy_host.bonded; energy.non_bonded[0] += energy_host.non_bonded; - if (energy.n_coulomb>=1) + if (energy.n_coulomb >= 1) energy.coulomb[0] += energy_host.coulomb; - if (energy.n_dipolar >=2) + if (energy.n_dipolar >= 2) energy.dipolar[1] += energy_host.dipolar; } diff --git a/src/core/cuda_interface.hpp b/src/core/cuda_interface.hpp index bcc318790f..e83456c1dc 100644 --- a/src/core/cuda_interface.hpp +++ b/src/core/cuda_interface.hpp @@ -23,8 +23,8 @@ #ifdef CUDA -#include "SystemInterface.hpp" #include "ParticleRange.hpp" +#include "SystemInterface.hpp" #ifdef ENGINE // velocities which need to be copied from the GPU to the CPU to calculate a @@ -69,7 +69,7 @@ struct CUDA_particle_data { /** particle position given from md part*/ float p[3]; -#if defined(LB_GPU) +#if defined(LB_GPU) /** particle momentum struct velocity p.m->v*/ float v[3]; #endif diff --git a/src/core/cuda_utils.hpp b/src/core/cuda_utils.hpp index 2c8b34d083..90857651c4 100755 --- a/src/core/cuda_utils.hpp +++ b/src/core/cuda_utils.hpp @@ -1,20 +1,20 @@ /* Copyright (C) 2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _CUDA_UTILS_HPP #define _CUDA_UTILS_HPP @@ -32,7 +32,7 @@ extern cudaStream_t stream[1]; extern cudaError_t CU_err; extern cudaError_t _err; -/**erroroutput for memory allocation and memory copy +/**erroroutput for memory allocation and memory copy * @param err cuda error code * @param *file .cu file were the error took place * @param line line of the file were the error took place @@ -41,18 +41,20 @@ extern cudaError_t _err; void _cuda_safe_mem(cudaError_t err, const char *file, unsigned int line); void _cuda_check_errors(const dim3 &block, const dim3 &grid, - const char *function, const char *file, unsigned int line); + const char *function, const char *file, + unsigned int line); #define cuda_safe_mem(a) _cuda_safe_mem((a), __FILE__, __LINE__) -#define KERNELCALL_shared(_f, _a, _b, _s, _params) \ - _f<<<_a, _b, _s, stream[0]>>>_params; \ +#define KERNELCALL_shared(_f, _a, _b, _s, _params) \ + _f<<<_a, _b, _s, stream[0]>>> _params; \ _cuda_check_errors(_a, _b, #_f, __FILE__, __LINE__); -#define KERNELCALL_stream(_function, _grid, _block, _stream, _params) \ - _function<<<_grid, _block, 0, _stream>>>_params; \ +#define KERNELCALL_stream(_function, _grid, _block, _stream, _params) \ + _function<<<_grid, _block, 0, _stream>>> _params; \ _cuda_check_errors(_grid, _block, #_function, __FILE__, __LINE__); -#define KERNELCALL(_f, _a, _b, _params) KERNELCALL_shared(_f, _a, _b, 0, _params) +#define KERNELCALL(_f, _a, _b, _params) \ + KERNELCALL_shared(_f, _a, _b, 0, _params) #endif diff --git a/src/core/debug.cpp b/src/core/debug.cpp index d24fd88a88..8502aafa72 100755 --- a/src/core/debug.cpp +++ b/src/core/debug.cpp @@ -236,7 +236,8 @@ void check_particle_sorting() { auto p = cell->part[n]; if (cell_structure.position_to_cell(p.r.p.data()) != cell) { fprintf(stderr, "%d: misplaced part id %d. %p != %p\n", this_node, - p.p.identity, (void*)cell, (void*)cell_structure.position_to_cell(p.r.p.data())); + p.p.identity, (void *)cell, + (void *)cell_structure.position_to_cell(p.r.p.data())); errexit(); } } diff --git a/src/core/debye_hueckel.hpp b/src/core/debye_hueckel.hpp index 19b81cf7b3..5aecabb966 100755 --- a/src/core/debye_hueckel.hpp +++ b/src/core/debye_hueckel.hpp @@ -75,15 +75,13 @@ inline void add_dh_coulomb_pair_force(Particle *p1, Particle *p2, double d[3], force[j] += fac * d[j]; ONEPART_TRACE(if (p1->p.identity == check_id) - fprintf(stderr, - "%d: OPT: DH f = (%.3e,%.3e,%.3e) with " - "part id=%d at dist %f fac %.3e\n", + fprintf(stderr, "%d: OPT: DH f = (%.3e,%.3e,%.3e) with " + "part id=%d at dist %f fac %.3e\n", this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], p2->p.identity, dist, fac)); ONEPART_TRACE(if (p2->p.identity == check_id) - fprintf(stderr, - "%d: OPT: DH f = (%.3e,%.3e,%.3e) with " - "part id=%d at dist %f fac %.3e\n", + fprintf(stderr, "%d: OPT: DH f = (%.3e,%.3e,%.3e) with " + "part id=%d at dist %f fac %.3e\n", this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], p1->p.identity, dist, fac)); } diff --git a/src/core/dihedral.cpp b/src/core/dihedral.cpp index f810090d61..57ecaf00b9 100755 --- a/src/core/dihedral.cpp +++ b/src/core/dihedral.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file dihedral.cpp * @@ -25,20 +25,19 @@ #include "dihedral.hpp" /// set dihedral parameters -int dihedral_set_params(int bond_type, int mult, double bend, double phase) -{ - if(bond_type < 0) +int dihedral_set_params(int bond_type, int mult, double bend, double phase) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); bonded_ia_params[bond_type].type = BONDED_IA_DIHEDRAL; - bonded_ia_params[bond_type].num = 3; + bonded_ia_params[bond_type].num = 3; bonded_ia_params[bond_type].p.dihedral.mult = mult; bonded_ia_params[bond_type].p.dihedral.bend = bend; bonded_ia_params[bond_type].p.dihedral.phase = phase; - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/dihedral.hpp b/src/core/dihedral.hpp index 3b13417d21..f00893d3e6 100755 --- a/src/core/dihedral.hpp +++ b/src/core/dihedral.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef DIHEDRAL_H #define DIHEDRAL_H @@ -26,9 +26,9 @@ * the maximal bond length! \ref forces.cpp */ -#include "utils.hpp" -#include "interaction_data.hpp" #include "grid.hpp" +#include "interaction_data.hpp" +#include "utils.hpp" #define ANGLE_NOT_DEFINED -100 @@ -37,16 +37,16 @@ int dihedral_set_params(int bond_type, int mult, double bend, double phase); /** Calculates the dihedral angle between particle quadruple p1, p2, p3 and p4. The dihedral angle is the angle between the planes -specified by the particle triples (p1,p2,p3) and (p2,p3,p4). +specified by the particle triples (p1,p2,p3) and (p2,p3,p4). Vectors a, b and c are the bond vectors between consequtive particles. If the a,b or b,c are parallel the dihedral angle is not defined in which case the routine returns phi=-1. Calling functions should check for that (Written by: Arijit Maitra) */ -inline void calc_dihedral_angle(Particle *p1, Particle *p2, Particle *p3, Particle *p4, - double a[3], double b[3], double c[3], - double aXb[3], double *l_aXb, double bXc[3], double *l_bXc, - double *cosphi, double *phi) -{ +inline void calc_dihedral_angle(Particle *p1, Particle *p2, Particle *p3, + Particle *p4, double a[3], double b[3], + double c[3], double aXb[3], double *l_aXb, + double bXc[3], double *l_bXc, double *cosphi, + double *phi) { int i; get_mi_vector(a, p2->r.p, p1->r.p); @@ -62,31 +62,36 @@ inline void calc_dihedral_angle(Particle *p1, Particle *p2, Particle *p3, Partic *l_bXc = sqrt(sqrlen(bXc)); /* catch case of undefined dihedral angle */ - if ( *l_aXb <= TINY_LENGTH_VALUE || *l_bXc <= TINY_LENGTH_VALUE ) { *phi = -1.0; *cosphi = 0; return;} + if (*l_aXb <= TINY_LENGTH_VALUE || *l_bXc <= TINY_LENGTH_VALUE) { + *phi = -1.0; + *cosphi = 0; + return; + } - for (i=0;i<3;i++) { + for (i = 0; i < 3; i++) { aXb[i] /= *l_aXb; bXc[i] /= *l_bXc; } *cosphi = scalar(aXb, bXc); - if ( fabs(fabs(*cosphi)-1) < TINY_SIN_VALUE ) *cosphi = dround(*cosphi); + if (fabs(fabs(*cosphi) - 1) < TINY_SIN_VALUE) + *cosphi = dround(*cosphi); /* Calculate dihedral angle */ *phi = acos(*cosphi); - if( scalar(aXb, c) < 0.0 ) *phi = (2.0*PI) - *phi; - + if (scalar(aXb, c) < 0.0) + *phi = (2.0 * PI) - *phi; } -/** calculate dihedral force between particles p1, p2 p3 and p4 +/** calculate dihedral force between particles p1, p2 p3 and p4 Written by Arijit Maitra, adapted to new force interface by Hanjo, more general new dihedral form by Ana. */ -inline int calc_dihedral_force(Particle *p2, Particle *p1, Particle *p3, Particle *p4, - Bonded_ia_parameters *iaparams, double force2[3], - double force1[3], double force3[3]) -{ +inline int calc_dihedral_force(Particle *p2, Particle *p1, Particle *p3, + Particle *p4, Bonded_ia_parameters *iaparams, + double force2[3], double force1[3], + double force3[3]) { int i; /* vectors for dihedral angle calculation */ double v12[3], v23[3], v34[3], v12Xv23[3], v23Xv34[3], l_v12Xv23, l_v23Xv34; @@ -97,66 +102,77 @@ inline int calc_dihedral_force(Particle *p2, Particle *p1, Particle *p3, Particl double fac, f1[3], f4[3]; /* dihedral angle */ - calc_dihedral_angle(p1, p2, p3, p4, v12, v23, v34, v12Xv23, &l_v12Xv23, v23Xv34, &l_v23Xv34, &cosphi, &phi); + calc_dihedral_angle(p1, p2, p3, p4, v12, v23, v34, v12Xv23, &l_v12Xv23, + v23Xv34, &l_v23Xv34, &cosphi, &phi); /* dihedral angle not defined - force zero */ - if ( phi == -1.0 ) { - for(i=0;i<3;i++) { force1[i] = 0.0; force2[i] = 0.0; force3[i] = 0.0; } + if (phi == -1.0) { + for (i = 0; i < 3; i++) { + force1[i] = 0.0; + force2[i] = 0.0; + force3[i] = 0.0; + } return 0; } /* calculate force components (directions) */ - for(i=0;i<3;i++) { - f1[i] = (v23Xv34[i] - cosphi*v12Xv23[i])/l_v12Xv23;; - f4[i] = (v12Xv23[i] - cosphi*v23Xv34[i])/l_v23Xv34; + for (i = 0; i < 3; i++) { + f1[i] = (v23Xv34[i] - cosphi * v12Xv23[i]) / l_v12Xv23; + ; + f4[i] = (v12Xv23[i] - cosphi * v23Xv34[i]) / l_v23Xv34; } vector_product(v23, f1, v23Xf1); vector_product(v23, f4, v23Xf4); vector_product(v34, f4, v34Xf4); vector_product(v12, f1, v12Xf1); - /* calculate force magnitude */ +/* calculate force magnitude */ #ifdef OLD_DIHEDRAL - fac = iaparams->p.dihedral.bend * iaparams->p.dihedral.phase * iaparams->p.dihedral.mult; + fac = iaparams->p.dihedral.bend * iaparams->p.dihedral.phase * + iaparams->p.dihedral.mult; #else fac = -iaparams->p.dihedral.bend * iaparams->p.dihedral.mult; #endif - if(fabs(sin(phi)) < TINY_SIN_VALUE) { + if (fabs(sin(phi)) < TINY_SIN_VALUE) { #ifdef OLD_DIHEDRAL - sinmphi_sinphi = iaparams->p.dihedral.mult * cos(2.0*PI - iaparams->p.dihedral.mult*phi)/cos(phi); + sinmphi_sinphi = iaparams->p.dihedral.mult * + cos(2.0 * PI - iaparams->p.dihedral.mult * phi) / cos(phi); #else /*(comes from taking the first term of the MacLaurin expansion of sin(n*phi - phi0) and sin(phi) and then making the division). The original code had a 2PI term in the cosine (cos(2PI - nPhi)) but I removed it because it wasn't doing anything. AnaVV*/ - sinmphi_sinphi = iaparams->p.dihedral.mult* - cos(iaparams->p.dihedral.mult*phi - iaparams->p.dihedral.phase)/cosphi; + sinmphi_sinphi = + iaparams->p.dihedral.mult * + cos(iaparams->p.dihedral.mult * phi - iaparams->p.dihedral.phase) / + cosphi; #endif - } - else { + } else { #ifdef OLD_DIHEDRAL - sinmphi_sinphi = sin(iaparams->p.dihedral.mult*phi)/sin(phi); + sinmphi_sinphi = sin(iaparams->p.dihedral.mult * phi) / sin(phi); #else - sinmphi_sinphi = sin(iaparams->p.dihedral.mult*phi - iaparams->p.dihedral.phase)/sin(phi); + sinmphi_sinphi = + sin(iaparams->p.dihedral.mult * phi - iaparams->p.dihedral.phase) / + sin(phi); #endif } fac *= sinmphi_sinphi; /* store dihedral forces */ - for(i=0;i<3;i++) { - force1[i] = fac*v23Xf1[i]; - force2[i] = fac*(v34Xf4[i] - v12Xf1[i] - v23Xf1[i]); - force3[i] = fac*(v12Xf1[i] - v23Xf4[i] - v34Xf4[i]); + for (i = 0; i < 3; i++) { + force1[i] = fac * v23Xf1[i]; + force2[i] = fac * (v34Xf4[i] - v12Xf1[i] - v23Xf1[i]); + force3[i] = fac * (v12Xf1[i] - v23Xf4[i] - v34Xf4[i]); } return 0; } -/** calculate dihedral energy between particles p1, p2 p3 and p4 +/** calculate dihedral energy between particles p1, p2 p3 and p4 Written by Arijit Maitra, adapted to new force interface by Hanjo */ -inline int dihedral_energy(Particle *p1, Particle *p2, Particle *p3, Particle *p4, - Bonded_ia_parameters *iaparams, double *_energy) -{ +inline int dihedral_energy(Particle *p1, Particle *p2, Particle *p3, + Particle *p4, Bonded_ia_parameters *iaparams, + double *_energy) { /* vectors for dihedral calculations. */ double v12[3], v23[3], v34[3], v12Xv23[3], v23Xv34[3], l_v12Xv23, l_v23Xv34; /* dihedral angle, cosine of the dihedral angle */ @@ -164,14 +180,15 @@ inline int dihedral_energy(Particle *p1, Particle *p2, Particle *p3, Particle *p /* energy factors */ double fac; - calc_dihedral_angle(p1, p2, p3, p4, v12, v23, v34, v12Xv23, &l_v12Xv23, v23Xv34, &l_v23Xv34, &cosphi, &phi); + calc_dihedral_angle(p1, p2, p3, p4, v12, v23, v34, v12Xv23, &l_v12Xv23, + v23Xv34, &l_v23Xv34, &cosphi, &phi); #ifdef OLD_DIHEDRAL - fac = iaparams->p.dihedral.phase * cos(iaparams->p.dihedral.mult*phi); + fac = iaparams->p.dihedral.phase * cos(iaparams->p.dihedral.mult * phi); #else - fac = -cos(iaparams->p.dihedral.mult*phi -iaparams->p.dihedral.phase); + fac = -cos(iaparams->p.dihedral.mult * phi - iaparams->p.dihedral.phase); #endif fac += 1.0; - fac *= iaparams->p.dihedral.bend; + fac *= iaparams->p.dihedral.bend; *_energy = fac; diff --git a/src/core/dpd.cpp b/src/core/dpd.cpp index 05d1ff71aa..63e58ca5c7 100755 --- a/src/core/dpd.cpp +++ b/src/core/dpd.cpp @@ -25,11 +25,11 @@ #ifdef DPD +#include "communication.hpp" +#include "global.hpp" #include "integrate.hpp" #include "random.hpp" #include "thermostat.hpp" -#include "communication.hpp" -#include "global.hpp" void dpd_heat_up() { double pref_scale = sqrt(3); @@ -120,20 +120,23 @@ static double weight(int type, double r_cut, double dist_inv) { } } -Vector3d dpd_pair_force(const Particle *p1, const Particle *p2, IA_parameters *ia_params, - double *d, double dist, double dist2) { +Vector3d dpd_pair_force(const Particle *p1, const Particle *p2, + IA_parameters *ia_params, double *d, double dist, + double dist2) { Vector3d f{}; auto const dist_inv = 1.0 / dist; if ((dist < ia_params->dpd_r_cut) && (ia_params->dpd_pref1 > 0.0)) { - auto const omega = weight(ia_params->dpd_wf, ia_params->dpd_r_cut, dist_inv); + auto const omega = + weight(ia_params->dpd_wf, ia_params->dpd_r_cut, dist_inv); auto const omega2 = Utils::sqr(omega); // DPD part // friction force prefactor double vel12_dot_d12 = 0.0; for (int j = 0; j < 3; j++) vel12_dot_d12 += (p1->m.v[j] - p2->m.v[j]) * d[j]; - auto const friction = ia_params->dpd_pref1 * omega2 * vel12_dot_d12 * time_step; + auto const friction = + ia_params->dpd_pref1 * omega2 * vel12_dot_d12 * time_step; // random force prefactor double noise; if (ia_params->dpd_pref2 > 0.0) { @@ -142,16 +145,18 @@ Vector3d dpd_pair_force(const Particle *p1, const Particle *p2, IA_parameters *i noise = 0.0; } for (int j = 0; j < 3; j++) { - f[j] += (noise - friction) * d[j]; + f[j] += (noise - friction) * d[j]; } } // DPD2 part if ((dist < ia_params->dpd_tr_cut) && (ia_params->dpd_pref3 > 0.0)) { - auto const omega = weight(ia_params->dpd_twf, ia_params->dpd_tr_cut, dist_inv); + auto const omega = + weight(ia_params->dpd_twf, ia_params->dpd_tr_cut, dist_inv); auto const omega2 = Utils::sqr(omega); - double P_times_dist_sqr[3][3] = {{dist2, 0, 0}, {0, dist2, 0}, {0, 0, dist2}}, - noise_vec[3]; + double P_times_dist_sqr[3] + [3] = {{dist2, 0, 0}, {0, dist2, 0}, {0, 0, dist2}}, + noise_vec[3]; for (int i = 0; i < 3; i++) { // noise vector if (ia_params->dpd_pref2 > 0.0) { diff --git a/src/core/dpd.hpp b/src/core/dpd.hpp index ab1eb48fe7..71bf74cddc 100755 --- a/src/core/dpd.hpp +++ b/src/core/dpd.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef CORE_DPD_HPP #define CORE_DPD_HPP @@ -26,7 +26,6 @@ * \ref forces.cpp */ - #include "config.hpp" #ifdef DPD @@ -37,16 +36,14 @@ void dpd_heat_up(); void dpd_cool_down(); void dpd_switch_off(); -int dpd_set_params(int part_type_a, int part_type_b, - double gamma, double r_c, int wf, - double tgamma, double tr_c, - int twf); +int dpd_set_params(int part_type_a, int part_type_b, double gamma, double r_c, + int wf, double tgamma, double tr_c, int twf); void dpd_init(); void dpd_update_params(double pref2_scale); -Vector3d dpd_pair_force(const Particle *p1, const Particle *p2, IA_parameters *ia_params, - double *d, double dist, double dist2); +Vector3d dpd_pair_force(const Particle *p1, const Particle *p2, + IA_parameters *ia_params, double *d, double dist, + double dist2); #endif #endif - diff --git a/src/core/elc.cpp b/src/core/elc.cpp index ef943f7f51..6b50313ae2 100755 --- a/src/core/elc.cpp +++ b/src/core/elc.cpp @@ -400,8 +400,9 @@ static double dipole_energy() { /* counter the P3M homogeneous background contribution to the boundaries. We never need that, since a homogeneous background spanning the artifical boundary layers is aphysical. */ - eng += pref * (-(gblcblk[1] * gblcblk[4] + gblcblk[0] * gblcblk[5]) - - (1. - 2. / 3.) * gblcblk[0] * gblcblk[1] * Utils::sqr(box_l[2])); + eng += pref * + (-(gblcblk[1] * gblcblk[4] + gblcblk[0] * gblcblk[5]) - + (1. - 2. / 3.) * gblcblk[0] * gblcblk[1] * Utils::sqr(box_l[2])); } return this_node == 0 ? eng : 0; @@ -832,7 +833,7 @@ static double Q_energy(double omega) { double eng = 0; double pref = 1 / omega; - for(unsigned ic = 0; ic < n_localpart; ic++) { + for (unsigned ic = 0; ic < n_localpart; ic++) { eng += pref * (partblk[size * ic + POQECM] * gblcblk[POQECP] + partblk[size * ic + POQESM] * gblcblk[POQESP] + partblk[size * ic + POQECP] * gblcblk[POQECM] + @@ -1069,7 +1070,8 @@ void ELC_add_force() { } for (p = 1; ux * (p - 1) < elc_params.far_cut && p <= n_scxcache; p++) { - for (q = 1; Utils::sqr(ux * (p - 1)) + Utils::sqr(uy * (q - 1)) < elc_params.far_cut2 && + for (q = 1; Utils::sqr(ux * (p - 1)) + Utils::sqr(uy * (q - 1)) < + elc_params.far_cut2 && q <= n_scycache; q++) { omega = C_2PI * sqrt(Utils::sqr(ux * p) + Utils::sqr(uy * q)); @@ -1109,7 +1111,8 @@ double ELC_energy() { checkpoint("E************distri q", 0, q, 2); } for (p = 1; ux * (p - 1) < elc_params.far_cut && p <= n_scxcache; p++) { - for (q = 1; Utils::sqr(ux * (p - 1)) + Utils::sqr(uy * (q - 1)) < elc_params.far_cut2 && + for (q = 1; Utils::sqr(ux * (p - 1)) + Utils::sqr(uy * (q - 1)) < + elc_params.far_cut2 && q <= n_scycache; q++) { omega = C_2PI * sqrt(Utils::sqr(ux * p) + Utils::sqr(uy * q)); diff --git a/src/core/elc.hpp b/src/core/elc.hpp index 1515563a4c..9731ae2b76 100755 --- a/src/core/elc.hpp +++ b/src/core/elc.hpp @@ -99,8 +99,8 @@ extern ELC_struct elc_params; @param bottom dielectric constant of lower part */ int ELC_set_params(double maxPWerror, double min_dist, double far_cut, - int neutralize, double delta_mid_top, double delta_mid_bot, int const_pot, - double pot_diff); + int neutralize, double delta_mid_top, double delta_mid_bot, + int const_pot, double pot_diff); /// the force calculation void ELC_add_force(); diff --git a/src/core/electrokinetics.cpp b/src/core/electrokinetics.cpp index 9f7f046dc5..05da99d4d9 100644 --- a/src/core/electrokinetics.cpp +++ b/src/core/electrokinetics.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "electrokinetics.hpp" - +#include "config.hpp" diff --git a/src/core/electrokinetics.hpp b/src/core/electrokinetics.hpp index cb2ba28f93..728bc45885 100755 --- a/src/core/electrokinetics.hpp +++ b/src/core/electrokinetics.hpp @@ -2,17 +2,17 @@ Copyright (C) 2010,2011,2012,2014,2015,2016 The ESPResSo project This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -23,9 +23,11 @@ #include "config.hpp" #include "lbboundaries.hpp" -//note that we need to declare the ek_parameters struct and instantiate it for LB_GPU -//to compile when electrokinetics is not compiled in. This seemed more elegant than -//ifdeffing multiple versions of the kernel integrate. +// note that we need to declare the ek_parameters struct and instantiate it for +// LB_GPU +// to compile when electrokinetics is not compiled in. This seemed more elegant +// than +// ifdeffing multiple versions of the kernel integrate. #ifdef CUDA #if defined(EK_DOUBLE_PREC) @@ -43,11 +45,12 @@ typedef void cufftComplex; typedef void cufftReal; #endif -/* Data structure holding parameters and memory pointers for the link flux system. */ +/* Data structure holding parameters and memory pointers for the link flux + * system. */ typedef struct { float agrid; - float time_step; //MD time step + float time_step; // MD time step float lb_density; unsigned int dim_x; unsigned int dim_x_padded; @@ -82,34 +85,33 @@ typedef struct { float *charge_potential_buffer; float *electric_field; #endif - float* charge_potential; - ekfloat* j; - float* lb_force_density_previous; - ekfloat* rho[MAX_NUMBER_OF_SPECIES]; + float *charge_potential; + ekfloat *j; + float *lb_force_density_previous; + ekfloat *rho[MAX_NUMBER_OF_SPECIES]; int species_index[MAX_NUMBER_OF_SPECIES]; float density[MAX_NUMBER_OF_SPECIES]; float D[MAX_NUMBER_OF_SPECIES]; float d[MAX_NUMBER_OF_SPECIES]; float valency[MAX_NUMBER_OF_SPECIES]; float ext_force_density[3][MAX_NUMBER_OF_SPECIES]; - char* node_is_catalyst; + char *node_is_catalyst; } EK_parameters; #endif #ifdef ELECTROKINETICS - /* Constants enumerating the links of a node in the link flux system EK_LINK_xyz - is the number of the link in direction (x, y, z), where x, y and z can be 0, - U or D representing 0 and one agrid in direction of or against the x, y or z - axis. The numbering differs from the one used in the LB since the LB - velocities are directed but the links are not. Links 0 - 8 represent - the odd LB velocities and numbers 13 - 21 represent the even LB velocities + is the number of the link in direction (x, y, z), where x, y and z can be 0, + U or D representing 0 and one agrid in direction of or against the x, y or z + axis. The numbering differs from the one used in the LB since the LB + velocities are directed but the links are not. Links 0 - 8 represent + the odd LB velocities and numbers 13 - 21 represent the even LB velocities (without the 0). In between there are the links connecting the corners, which - represent the 3rd shell not used in the LB but in the advection. The + represent the 3rd shell not used in the LB but in the advection. The following 13 constants are only defined for the sake of completeness.*/ - + #define EK_LINK_U00 0 #define EK_LINK_0U0 1 #define EK_LINK_00U 2 @@ -140,24 +142,23 @@ typedef struct { #define EK_LINK_DUD 24 #define EK_LINK_DUU 25 - extern EK_parameters ek_parameters; extern int ek_initialized; void ek_integrate(); void ek_print_parameters(); void ek_print_lbpar(); -void lb_set_ek_pointer(EK_parameters* pointeradress); +void lb_set_ek_pointer(EK_parameters *pointeradress); unsigned int ek_calculate_boundary_mass(); -int ek_print_vtk_density(int species, char* filename); -int ek_print_vtk_flux(int species, char* filename); -int ek_print_vtk_potential(char* filename); +int ek_print_vtk_density(int species, char *filename); +int ek_print_vtk_flux(int species, char *filename); +int ek_print_vtk_potential(char *filename); #ifdef EK_ELECTROSTATIC_COUPLING -int ek_print_vtk_particle_potential( char* filename ); +int ek_print_vtk_particle_potential(char *filename); #endif -int ek_print_vtk_lbforce_density(char* filename); -int ek_lb_print_vtk_density(char* filename); -int ek_lb_print_vtk_velocity(char* filename); +int ek_print_vtk_lbforce_density(char *filename); +int ek_lb_print_vtk_density(char *filename); +int ek_lb_print_vtk_velocity(char *filename); int ek_init(); int ek_set_agrid(double agrid); int ek_set_lb_density(double lb_density); @@ -166,35 +167,37 @@ int ek_set_friction(double friction); int ek_set_T(double T); int ek_set_prefactor(double prefactor); #ifdef EK_ELECTROSTATIC_COUPLING -int ek_set_electrostatics_coupling( bool electrostatics_coupling ); +int ek_set_electrostatics_coupling(bool electrostatics_coupling); void ek_calculate_electrostatic_coupling(); #endif int ek_set_bulk_viscosity(double bulk_viscosity); int ek_set_gamma_odd(double gamma_odd); int ek_set_gamma_even(double gamma_even); -int ek_set_lb_force_density(double* ext_force_density); +int ek_set_lb_force_density(double *ext_force_density); int ek_set_density(int species, double density); int ek_set_D(int species, double D); int ek_set_valency(int species, double valency); -int ek_set_ext_force_density(int species, double ext_force_density_x, double ext_force_density_y, double ext_force_density_z); +int ek_set_ext_force_density(int species, double ext_force_density_x, + double ext_force_density_y, + double ext_force_density_z); int ek_set_stencil(int stencil); int ek_set_advection(bool advection); int ek_set_fluidcoupling(bool ideal_contribution); -int ek_node_print_velocity(int x, int y, int z, double* velocity); -int ek_node_print_density(int species, int x, int y, int z, double* density); -int ek_node_print_flux(int species, int x, int y, int z, double* flux); -int ek_node_print_potential(int x, int y, int z, double* potential); +int ek_node_print_velocity(int x, int y, int z, double *velocity); +int ek_node_print_density(int species, int x, int y, int z, double *density); +int ek_node_print_flux(int species, int x, int y, int z, double *flux); +int ek_node_print_potential(int x, int y, int z, double *potential); int ek_node_set_density(int species, int x, int y, int z, double density); -ekfloat ek_calculate_net_charge(); -int ek_neutralize_system(int species); -int ek_save_checkpoint(char* filename); -int ek_load_checkpoint(char* filename); - +ekfloat ek_calculate_net_charge(); +int ek_neutralize_system(int species); +int ek_save_checkpoint(char *filename); +int ek_load_checkpoint(char *filename); + #ifdef EK_BOUNDARIES -void ek_init_species_density_wallcharge(ekfloat* wallcharge_species_density, int wallcharge_species); +void ek_init_species_density_wallcharge(ekfloat *wallcharge_species_density, + int wallcharge_species); #endif - #endif /* CUDA */ #endif /* ELECTROKINETICS_H */ diff --git a/src/core/electrokinetics_pdb_parse.cpp b/src/core/electrokinetics_pdb_parse.cpp index bfca0d8899..84e04bed22 100755 --- a/src/core/electrokinetics_pdb_parse.cpp +++ b/src/core/electrokinetics_pdb_parse.cpp @@ -1,30 +1,30 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* vim: set ts=8 sts=2 sw=2 et: */ +#include +#include +#include +#include #include #include #include -#include -#include #include -#include -#include #include "electrokinetics_pdb_parse.hpp" @@ -36,8 +36,8 @@ const int pdb_SUCCESS = 0; const int pdb_ERROR = 1; -float* pdb_charge_lattice = nullptr; -int* pdb_boundary_lattice = nullptr; +float *pdb_charge_lattice = nullptr; +int *pdb_boundary_lattice = nullptr; typedef struct { float max_x; @@ -51,39 +51,39 @@ typedef struct { /* BEGIN CODE */ -void galloc(void** ptr, size_t size) { +void galloc(void **ptr, size_t size) { if (!*ptr) { if (size > 0) { - *ptr = (void*) Utils::malloc(size); - } - else { + *ptr = (void *)Utils::malloc(size); + } else { printf("You cannot malloc to size 0\n"); } - } - else { + } else { if (size > 0) { *ptr = Utils::realloc(*ptr, size); - } - else { + } else { free(*ptr); *ptr = nullptr; } } } -unsigned int pdb_rhoindex_cartesian2linear(unsigned int x, unsigned int y, unsigned int z) { - return z * ek_parameters.dim_y * ek_parameters.dim_x + y * ek_parameters.dim_x + x; +unsigned int pdb_rhoindex_cartesian2linear(unsigned int x, unsigned int y, + unsigned int z) { + return z * ek_parameters.dim_y * ek_parameters.dim_x + + y * ek_parameters.dim_x + x; } -int print_charge_field(char* filename) { - FILE* fp; - if ((fp = fopen(filename,"w")) == nullptr) return pdb_ERROR; - - if( fp == nullptr ) { +int print_charge_field(char *filename) { + FILE *fp; + if ((fp = fopen(filename, "w")) == nullptr) + return pdb_ERROR; + + if (fp == nullptr) { return 1; } - - fprintf( fp, "\ + + fprintf(fp, "\ # vtk DataFile Version 2.0\n\ charge_density\n\ ASCII\n\ @@ -96,28 +96,32 @@ SPACING %f %f %f\n\ POINT_DATA %u\n\ SCALARS charge_density float 1\n\ LOOKUP_TABLE default\n", - ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z, - ek_parameters.agrid*0.5f, ek_parameters.agrid*0.5f, ek_parameters.agrid*0.5f, - ek_parameters.agrid, ek_parameters.agrid, ek_parameters.agrid, - ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); - - for( unsigned int i = 0; i < (ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); i++ ) { - fprintf( fp, "%e ", pdb_charge_lattice[i] ); + ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z, + ek_parameters.agrid * 0.5f, ek_parameters.agrid * 0.5f, + ek_parameters.agrid * 0.5f, ek_parameters.agrid, ek_parameters.agrid, + ek_parameters.agrid, + ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); + + for (unsigned int i = 0; + i < (ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); + i++) { + fprintf(fp, "%e ", pdb_charge_lattice[i]); } - - fclose( fp ); + + fclose(fp); return pdb_SUCCESS; } -int print_boundary_lattice(char* filename) { - FILE* fp; - if ((fp = fopen(filename,"w")) == nullptr) return pdb_ERROR; - - if( fp == nullptr ) { +int print_boundary_lattice(char *filename) { + FILE *fp; + if ((fp = fopen(filename, "w")) == nullptr) + return pdb_ERROR; + + if (fp == nullptr) { return 1; } - - fprintf( fp, "\ + + fprintf(fp, "\ # vtk DataFile Version 2.0\n\ boundary_flag\n\ ASCII\n\ @@ -130,35 +134,40 @@ SPACING %f %f %f\n\ POINT_DATA %u\n\ SCALARS boundary_flag float 1\n\ LOOKUP_TABLE default\n", - ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z, - ek_parameters.agrid*0.5f, ek_parameters.agrid*0.5f, ek_parameters.agrid*0.5f, - ek_parameters.agrid, ek_parameters.agrid, ek_parameters.agrid, - ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); - - for( unsigned int i = 0; i < (ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); i++ ) { - fprintf( fp, "%d ", pdb_boundary_lattice[i] ); + ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z, + ek_parameters.agrid * 0.5f, ek_parameters.agrid * 0.5f, + ek_parameters.agrid * 0.5f, ek_parameters.agrid, ek_parameters.agrid, + ek_parameters.agrid, + ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); + + for (unsigned int i = 0; + i < (ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z); + i++) { + fprintf(fp, "%d ", pdb_boundary_lattice[i]); } - - fclose( fp ); + + fclose(fp); return pdb_SUCCESS; } int populate_lattice(PdbParser::PdbParser &parser, double scale) { - /* - * This routine will populate the lattice using the - * values read from the pdb and itp files. - * WARNING: It contains much logic and interpolation stuff! - */ +/* + * This routine will populate the lattice using the + * values read from the pdb and itp files. + * WARNING: It contains much logic and interpolation stuff! + */ #ifdef DEBUG - printf("pdb_n_particles=%u, itp_n_particles=%u, itp_n_parameters=%u\n",atom_data->pdb_n_particles,atom_data->itp_n_particles,atom_data->itp_n_parameters); + printf("pdb_n_particles=%u, itp_n_particles=%u, itp_n_parameters=%u\n", + atom_data->pdb_n_particles, atom_data->itp_n_particles, + atom_data->itp_n_parameters); #endif // TODO: Check if bounding box fits into simbox const PdbParser::BoundingBox bbox = parser.calc_bounding_box(); float center[3]; - - center[0] = ( bbox.urx + bbox.llx )/2 / scale; - center[1] = ( bbox.ury + bbox.lly )/2 / scale; - center[2] = ( bbox.urz + bbox.llz )/2 / scale; + + center[0] = (bbox.urx + bbox.llx) / 2 / scale; + center[1] = (bbox.ury + bbox.lly) / 2 / scale; + center[2] = (bbox.urz + bbox.llz) / 2 / scale; // calculate the shift of the bounding box float shift[3]; @@ -167,8 +176,9 @@ int populate_lattice(PdbParser::PdbParser &parser, double scale) { shift[2] = ek_parameters.agrid / 2.0 * ek_parameters.dim_z - center[2]; #ifdef DEBUG - printf("agrid=%f, dim_x=%d, dim_y=%d, dim_z=%d\n",ek_parameters.agrid, ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z); - printf("shift=[%f; %f; %f]\n",shift[0], shift[1], shift[2]); + printf("agrid=%f, dim_x=%d, dim_y=%d, dim_z=%d\n", ek_parameters.agrid, + ek_parameters.dim_x, ek_parameters.dim_y, ek_parameters.dim_z); + printf("shift=[%f; %f; %f]\n", shift[0], shift[1], shift[2]); #endif // joining the array @@ -178,11 +188,14 @@ int populate_lattice(PdbParser::PdbParser &parser, double scale) { float a_x_shifted, a_y_shifted, a_z_shifted; float a_x_scaled, a_y_scaled, a_z_scaled; - for (std::vector::const_iterator a = parser.pdb_atoms.begin(); a != parser.pdb_atoms.end(); ++a) { + for (std::vector::const_iterator a = + parser.pdb_atoms.begin(); + a != parser.pdb_atoms.end(); ++a) { PdbParser::itp_atom b = parser.itp_atoms[a->i]; PdbParser::itp_atomtype c = parser.itp_atomtypes[b.type]; #ifdef DEBUG - printf("i=%d x=%f y=%f z=%f type=%s charge=%f sigma=%f epsilon=%f\n",a->i,a->x,a->y,a->z,b.type,b.charge,c.sigma,c.epsilon); + printf("i=%d x=%f y=%f z=%f type=%s charge=%f sigma=%f epsilon=%f\n", a->i, + a->x, a->y, a->z, b.type, b.charge, c.sigma, c.epsilon); #endif a_x_scaled = a->x / scale; @@ -190,102 +203,143 @@ int populate_lattice(PdbParser::PdbParser &parser, double scale) { a_z_scaled = a->z / scale; // Interpolate the charge to the lattice - gridpos = (a_x_scaled + shift[0]) / ek_parameters.agrid - 0.5f; - lowernode[0] = (int) floorf( gridpos ); - cellpos[0] = gridpos - lowernode[0]; - - gridpos = (a_y_scaled + shift[1]) / ek_parameters.agrid - 0.5f; - lowernode[1] = (int) floorf( gridpos ); - cellpos[1] = gridpos - lowernode[1]; - - gridpos = (a_z_scaled + shift[2]) / ek_parameters.agrid - 0.5f; - lowernode[2] = (int) floorf( gridpos ); - cellpos[2] = gridpos - lowernode[2]; - - lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; - lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; - lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; - - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],lowernode[2] )] - += b.charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); + gridpos = (a_x_scaled + shift[0]) / ek_parameters.agrid - 0.5f; + lowernode[0] = (int)floorf(gridpos); + cellpos[0] = gridpos - lowernode[0]; - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],lowernode[2] )] - += b.charge * cellpos[0] * ( 1 - cellpos[1] ) * ( 1 - cellpos[2] ); + gridpos = (a_y_scaled + shift[1]) / ek_parameters.agrid - 0.5f; + lowernode[1] = (int)floorf(gridpos); + cellpos[1] = gridpos - lowernode[1]; - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] - += b.charge * ( 1 - cellpos[0] ) * cellpos[1] * ( 1 - cellpos[2] ); + gridpos = (a_z_scaled + shift[2]) / ek_parameters.agrid - 0.5f; + lowernode[2] = (int)floorf(gridpos); + cellpos[2] = gridpos - lowernode[2]; - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] - += b.charge * ( 1 - cellpos[0] ) * ( 1 - cellpos[1] ) * cellpos[2]; - - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,lowernode[2] )] - += b.charge * cellpos[0] * cellpos[1] * ( 1 - cellpos[2] ); - - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,lowernode[1],( lowernode[2] + 1 ) % ek_parameters.dim_z )] - += b.charge * cellpos[0] * ( 1 - cellpos[1] ) * cellpos[2]; - - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( lowernode[0],( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] - += b.charge * ( 1 - cellpos[0] ) * cellpos[1] * cellpos[2]; + lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; + lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; + lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; - pdb_charge_lattice[pdb_rhoindex_cartesian2linear( ( lowernode[0] + 1 ) % ek_parameters.dim_x,( lowernode[1] + 1 ) % ek_parameters.dim_y,( lowernode[2] + 1 ) % ek_parameters.dim_z )] - += b.charge * cellpos[0] * cellpos[1] * cellpos[2]; + pdb_charge_lattice[pdb_rhoindex_cartesian2linear(lowernode[0], lowernode[1], + lowernode[2])] += + b.charge * (1 - cellpos[0]) * (1 - cellpos[1]) * (1 - cellpos[2]); + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + (lowernode[0] + 1) % ek_parameters.dim_x, lowernode[1], + lowernode[2])] += + b.charge * cellpos[0] * (1 - cellpos[1]) * (1 - cellpos[2]); + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + lowernode[0], (lowernode[1] + 1) % ek_parameters.dim_y, + lowernode[2])] += + b.charge * (1 - cellpos[0]) * cellpos[1] * (1 - cellpos[2]); + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + lowernode[0], lowernode[1], + (lowernode[2] + 1) % ek_parameters.dim_z)] += + b.charge * (1 - cellpos[0]) * (1 - cellpos[1]) * cellpos[2]; + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + (lowernode[0] + 1) % ek_parameters.dim_x, + (lowernode[1] + 1) % ek_parameters.dim_y, lowernode[2])] += + b.charge * cellpos[0] * cellpos[1] * (1 - cellpos[2]); + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + (lowernode[0] + 1) % ek_parameters.dim_x, lowernode[1], + (lowernode[2] + 1) % ek_parameters.dim_z)] += + b.charge * cellpos[0] * (1 - cellpos[1]) * cellpos[2]; + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + lowernode[0], (lowernode[1] + 1) % ek_parameters.dim_y, + (lowernode[2] + 1) % ek_parameters.dim_z)] += + b.charge * (1 - cellpos[0]) * cellpos[1] * cellpos[2]; + + pdb_charge_lattice[pdb_rhoindex_cartesian2linear( + (lowernode[0] + 1) % ek_parameters.dim_x, + (lowernode[1] + 1) % ek_parameters.dim_y, + (lowernode[2] + 1) % ek_parameters.dim_z)] += + b.charge * cellpos[0] * cellpos[1] * cellpos[2]; // Interpolate lennard-jones parameters to boundary - float r = pow(2,1./6.)*c.sigma * 10 / scale; + float r = pow(2, 1. / 6.) * c.sigma * 10 / scale; a_x_shifted = (a_x_scaled + shift[0]) / ek_parameters.agrid - 0.5f; a_y_shifted = (a_y_scaled + shift[1]) / ek_parameters.agrid - 0.5f; a_z_shifted = (a_z_scaled + shift[2]) / ek_parameters.agrid - 0.5f; - for (float z = a_z_scaled - r; z <= a_z_scaled + r + ek_parameters.agrid; z += ek_parameters.agrid) { - for (float y = a_y_scaled - r; y <= a_y_scaled + r + ek_parameters.agrid; y += ek_parameters.agrid) { - for (float x = a_x_scaled - r; x <= a_x_scaled + r + ek_parameters.agrid; x += ek_parameters.agrid) { - gridpos = (x + shift[0]) / ek_parameters.agrid - 0.5f; - lowernode[0] = (int) floorf( gridpos ); - - gridpos = (y + shift[1]) / ek_parameters.agrid - 0.5f; - lowernode[1] = (int) floorf( gridpos ); - - gridpos = (z + shift[2]) / ek_parameters.agrid - 0.5f; - lowernode[2] = (int) floorf( gridpos ); - - lowernode[0] = (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; - lowernode[1] = (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; - lowernode[2] = (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; + for (float z = a_z_scaled - r; z <= a_z_scaled + r + ek_parameters.agrid; + z += ek_parameters.agrid) { + for (float y = a_y_scaled - r; y <= a_y_scaled + r + ek_parameters.agrid; + y += ek_parameters.agrid) { + for (float x = a_x_scaled - r; + x <= a_x_scaled + r + ek_parameters.agrid; + x += ek_parameters.agrid) { + gridpos = (x + shift[0]) / ek_parameters.agrid - 0.5f; + lowernode[0] = (int)floorf(gridpos); + + gridpos = (y + shift[1]) / ek_parameters.agrid - 0.5f; + lowernode[1] = (int)floorf(gridpos); + + gridpos = (z + shift[2]) / ek_parameters.agrid - 0.5f; + lowernode[2] = (int)floorf(gridpos); + + lowernode[0] = + (lowernode[0] + ek_parameters.dim_x) % ek_parameters.dim_x; + lowernode[1] = + (lowernode[1] + ek_parameters.dim_y) % ek_parameters.dim_y; + lowernode[2] = + (lowernode[2] + ek_parameters.dim_z) % ek_parameters.dim_z; #ifdef DEBUG - printf("shifted: %f %f %f\n", a_x_shifted, a_y_shifted, a_z_shifted); - printf("lowernode: %d %d %d\n", lowernode[0], lowernode[1], lowernode[2]); - printf("distance: %f %f %f\n", lowernode[0] - a_x_shifted, lowernode[1] - a_y_shifted, lowernode[2] - a_z_shifted); - printf("distance: %f <= %f\n\n", pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2), pow(r/ek_parameters.agrid,2)); + printf("shifted: %f %f %f\n", a_x_shifted, a_y_shifted, a_z_shifted); + printf("lowernode: %d %d %d\n", lowernode[0], lowernode[1], + lowernode[2]); + printf("distance: %f %f %f\n", lowernode[0] - a_x_shifted, + lowernode[1] - a_y_shifted, lowernode[2] - a_z_shifted); + printf("distance: %f <= %f\n\n", + pow(lowernode[0] - a_x_shifted, 2) + + pow(lowernode[1] - a_y_shifted, 2) + + pow(lowernode[2] - a_z_shifted, 2), + pow(r / ek_parameters.agrid, 2)); #endif - if ( pow(lowernode[0] - a_x_shifted,2) + pow(lowernode[1] - a_y_shifted,2) + pow(lowernode[2] - a_z_shifted,2) <= pow(r/ek_parameters.agrid,2) ) { - pdb_boundary_lattice[ek_parameters.dim_y*ek_parameters.dim_x*lowernode[2] + ek_parameters.dim_x*lowernode[1] + lowernode[0]] = 1; - } - } + if (pow(lowernode[0] - a_x_shifted, 2) + + pow(lowernode[1] - a_y_shifted, 2) + + pow(lowernode[2] - a_z_shifted, 2) <= + pow(r / ek_parameters.agrid, 2)) { + pdb_boundary_lattice[ek_parameters.dim_y * ek_parameters.dim_x * + lowernode[2] + + ek_parameters.dim_x * lowernode[1] + + lowernode[0]] = 1; + } + } } } - } return pdb_SUCCESS; } -int pdb_parse(char* pdb_filename, char* itp_filename, double scale) { +int pdb_parse(char *pdb_filename, char *itp_filename, double scale) { /* * This is the main parsing routine, which is visible to the outside - * through the header electrokinetics_pdb_parse.h. It doesn't contain any logic and just + * through the header electrokinetics_pdb_parse.h. It doesn't contain any + * logic and just * deploys the input to the subroutines. */ /* BEGIN DEPLOY */ - galloc( (void**) &pdb_charge_lattice, ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z * sizeof(float)); - galloc( (void**) &pdb_boundary_lattice, ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z * sizeof(int)); - for ( unsigned int i = 0; i < ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z; i++ ) { + galloc((void **)&pdb_charge_lattice, ek_parameters.dim_x * + ek_parameters.dim_y * + ek_parameters.dim_z * sizeof(float)); + galloc((void **)&pdb_boundary_lattice, ek_parameters.dim_x * + ek_parameters.dim_y * + ek_parameters.dim_z * sizeof(int)); + for (unsigned int i = 0; + i < ek_parameters.dim_x * ek_parameters.dim_y * ek_parameters.dim_z; + i++) { pdb_charge_lattice[i] = 0.0; pdb_boundary_lattice[i] = 0; } PdbParser::PdbParser parser; - if(!parser.parse_file(pdb_filename, itp_filename)) + if (!parser.parse_file(pdb_filename, itp_filename)) return pdb_ERROR; return populate_lattice(parser, scale); diff --git a/src/core/electrokinetics_pdb_parse.hpp b/src/core/electrokinetics_pdb_parse.hpp index eeb3cc4676..7ea1e360ac 100644 --- a/src/core/electrokinetics_pdb_parse.hpp +++ b/src/core/electrokinetics_pdb_parse.hpp @@ -1,20 +1,20 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* vim: set ts=8 sts=2 sw=2 et: */ #ifndef _ELECTROKINETICS_PDB_PARSE_HPP @@ -24,15 +24,15 @@ #ifdef EK_BOUNDARIES -extern float* pdb_charge_lattice; -extern int* pdb_boundary_lattice; +extern float *pdb_charge_lattice; +extern int *pdb_boundary_lattice; /* Returns 0/1 if reading the files was successful/unsuccessful */ -int pdb_parse(char* pdb_filename, char* itp_filename, double scale); +int pdb_parse(char *pdb_filename, char *itp_filename, double scale); -int print_charge_field(char* filename); +int print_charge_field(char *filename); -int print_boundary_lattice(char* filename); +int print_boundary_lattice(char *filename); #else /* that is tested for in a number of places, make sure that pdb diff --git a/src/core/energy.cpp b/src/core/energy.cpp index 02eda2347e..6450ca8a2c 100755 --- a/src/core/energy.cpp +++ b/src/core/energy.cpp @@ -23,6 +23,7 @@ */ #include "EspressoSystemInterface.hpp" +#include "constraints.hpp" #include "cuda_interface.hpp" #include "energy_inline.hpp" #include "forces.hpp" @@ -31,15 +32,14 @@ #include "magnetic_non_p3m_methods.hpp" #include "mdlc_correction.hpp" #include "scafacos.hpp" -#include "constraints.hpp" #include #include "short_range_loop.hpp" ActorList energyActors; -Observable_stat energy = {0, {}, 0,0,0}; -Observable_stat total_energy = {0, {}, 0,0,0}; +Observable_stat energy = {0, {}, 0, 0, 0}; +Observable_stat total_energy = {0, {}, 0, 0, 0}; /************************************************************/ @@ -96,8 +96,8 @@ void init_energies(Observable_stat *stat) { n_dipolar = 2; break; #ifdef DIPOLAR_BARNES_HUT - case DIPOLAR_BH_GPU: - n_dipolar = 2; + case DIPOLAR_BH_GPU: + n_dipolar = 2; break; #endif case DIPOLAR_SCAFACOS: @@ -107,11 +107,9 @@ void init_energies(Observable_stat *stat) { #endif - obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, n_coulomb, - n_dipolar, 0, 1); + obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, + n_coulomb, n_dipolar, 0, 1); stat->init_status = 0; - - } /************************************************************/ @@ -161,7 +159,6 @@ void energy_calc(double *result) { /* gather data */ MPI_Reduce(energy.data.e, result, energy.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); - } /************************************************************/ @@ -270,18 +267,18 @@ void calc_long_range_energies() { #endif /* ifdef DIPOLES */ } -double calculate_current_potential_energy_of_system(){ - //calculate potential energy - if (total_energy.init_status == 0) { - init_energies(&total_energy); - master_energy_calc(); - } - int num_energies=total_energy.data.n; - double kinetic_energy =total_energy.data.e[0]; - double sum_all_energies=0; - for(int i=0;i. + along with this program. If not, see . */ /** \file energy.hpp Implementation of the energy calculation. @@ -26,8 +26,8 @@ #define _ENERGY_H /* include the energy files */ -#include "statistics.hpp" #include "actor/ActorList.hpp" +#include "statistics.hpp" /** \name Exported Variables */ /************************************************************/ @@ -49,14 +49,13 @@ void init_energies(Observable_stat *stat); void master_energy_calc(); /** parallel energy calculation. - @param result non-zero only on master node; will contain the cumulative over all nodes. */ + @param result non-zero only on master node; will contain the cumulative over + all nodes. */ void energy_calc(double *result); - /** Calculate long range energies (P3M, MMM2d...). */ void calc_long_range_energies(); - /** Calculate the total energy */ double calculate_current_potential_energy_of_system(); diff --git a/src/core/energy_inline.hpp b/src/core/energy_inline.hpp index 5b9b6ef8a4..4fc4b14342 100644 --- a/src/core/energy_inline.hpp +++ b/src/core/energy_inline.hpp @@ -29,7 +29,6 @@ #include "bmhtf-nacl.hpp" #include "buckingham.hpp" #include "dihedral.hpp" -#include "thermalized_bond.hpp" #include "fene.hpp" #include "gaussian.hpp" #include "gb.hpp" @@ -48,8 +47,9 @@ #include "statistics.hpp" #include "steppot.hpp" #include "tab.hpp" -#include "thole.hpp" +#include "thermalized_bond.hpp" #include "thermostat.hpp" +#include "thole.hpp" #include "umbrella.hpp" #ifdef ELECTROSTATICS #include "bonded_coulomb.hpp" @@ -81,9 +81,11 @@ @param dist2 distance squared between p1 and p2. @return the short ranged interaction energy between the two particles */ -inline double calc_non_bonded_pair_energy(const Particle *p1, const Particle *p2, - const IA_parameters *ia_params, const double d[3], - double dist, double dist2) { +inline double calc_non_bonded_pair_energy(const Particle *p1, + const Particle *p2, + const IA_parameters *ia_params, + const double d[3], double dist, + double dist2) { double ret = 0; #ifdef NO_INTRA_NB @@ -191,8 +193,8 @@ inline void add_non_bonded_pair_energy(Particle *p1, Particle *p2, double d[3], #ifdef EXCLUSIONS if (do_nonbonded(p1, p2)) #endif - *obsstat_nonbonded(&energy, p1->p.type, p2->p.type) += - calc_non_bonded_pair_energy(p1, p2, ia_params, d, dist, dist2); + *obsstat_nonbonded(&energy, p1->p.type, p2->p.type) += + calc_non_bonded_pair_energy(p1, p2, ia_params, d, dist, dist2); #ifdef ELECTROSTATICS if (coulomb.method != COULOMB_NONE) { @@ -334,7 +336,8 @@ inline void add_bonded_energy(Particle *p1) { #endif #ifdef P3M case BONDED_IA_BONDED_COULOMB_P3M_SR: - bond_broken = bonded_coulomb_p3m_sr_pair_energy(p1, p2, iaparams, dx, &ret); + bond_broken = + bonded_coulomb_p3m_sr_pair_energy(p1, p2, iaparams, dx, &ret); break; #endif #ifdef LENNARD_JONES @@ -439,18 +442,18 @@ inline void add_kinetic_energy(Particle *p1) { #endif /* kinetic energy */ - energy.data.e[0] += - (Utils::sqr(p1->m.v[0]) + Utils::sqr(p1->m.v[1]) + Utils::sqr(p1->m.v[2])) * 0.5 * p1->p.mass; + energy.data.e[0] += (Utils::sqr(p1->m.v[0]) + Utils::sqr(p1->m.v[1]) + + Utils::sqr(p1->m.v[2])) * + 0.5 * p1->p.mass; #ifdef ROTATION - if (p1->p.rotation) - { + if (p1->p.rotation) { /* the rotational part is added to the total kinetic energy; Here we use the rotational inertia */ energy.data.e[0] += 0.5 * (Utils::sqr(p1->m.omega[0]) * p1->p.rinertia[0] + - Utils::sqr(p1->m.omega[1]) * p1->p.rinertia[1] + - Utils::sqr(p1->m.omega[2]) * p1->p.rinertia[2]); + Utils::sqr(p1->m.omega[1]) * p1->p.rinertia[1] + + Utils::sqr(p1->m.omega[2]) * p1->p.rinertia[2]); } #endif } diff --git a/src/core/errorhandling.hpp b/src/core/errorhandling.hpp index 207bdd0b21..ae5bc9482a 100755 --- a/src/core/errorhandling.hpp +++ b/src/core/errorhandling.hpp @@ -103,9 +103,9 @@ RuntimeErrorStream _runtimeMessageStream(RuntimeError::ErrorLevel level, ErrorHandling::RuntimeError::ErrorLevel::ERROR, __FILE__, __LINE__, \ __PRETTYFUNC__) -#define runtimeWarningMsg() \ +#define runtimeWarningMsg() \ ErrorHandling::_runtimeMessageStream( \ - ErrorHandling::RuntimeError::ErrorLevel::WARNING, __FILE__, __LINE__, \ + ErrorHandling::RuntimeError::ErrorLevel::WARNING, __FILE__, __LINE__, \ __PRETTYFUNC__) #define debugMsg() \ diff --git a/src/core/fd-electrostatics.hpp b/src/core/fd-electrostatics.hpp index 924fc96161..e6b7102d08 100644 --- a/src/core/fd-electrostatics.hpp +++ b/src/core/fd-electrostatics.hpp @@ -1,7 +1,6 @@ #ifndef _FD_ELECTROSTATICS_HPP #define _FD_ELECTROSTATICS_HPP - #ifdef __CUDACC__ #include @@ -16,54 +15,54 @@ typedef void cufftReal; #define PI_FLOAT 3.14159265358979323846f - class FdElectrostatics { - public: - struct InputParameters { - float prefactor; - int dim_x, dim_y, dim_z; - float agrid; - }; - - struct Parameters : public InputParameters { - Parameters() {} - Parameters(InputParameters& inputParameters) : InputParameters(inputParameters) - { - charge_potential = 0; - greensfcn = 0; - dim_x_padded = (inputParameters.dim_x/2+1)*2; - } - - cufftComplex *charge_potential; - cufftReal *greensfcn; - int dim_x_padded; - }; - - struct Grid { - float* grid; - int dim_x; - int dim_y; - int dim_z; - float agrid; - }; - - ~FdElectrostatics(); - FdElectrostatics(InputParameters inputParameters, cudaStream_t stream); - void calculatePotential(); - void calculatePotential(cufftComplex *charge_potential); - Grid getGrid(); - - private: - Parameters parameters; - cudaStream_t cuda_stream; - cufftHandle plan_fft; - cufftHandle plan_ifft; - bool initialized; +public: + struct InputParameters { + float prefactor; + int dim_x, dim_y, dim_z; + float agrid; + }; + + struct Parameters : public InputParameters { + Parameters() {} + Parameters(InputParameters &inputParameters) + : InputParameters(inputParameters) { + charge_potential = 0; + greensfcn = 0; + dim_x_padded = (inputParameters.dim_x / 2 + 1) * 2; + } + + cufftComplex *charge_potential; + cufftReal *greensfcn; + int dim_x_padded; + }; + + struct Grid { + float *grid; + int dim_x; + int dim_y; + int dim_z; + float agrid; + }; + + ~FdElectrostatics(); + FdElectrostatics(InputParameters inputParameters, cudaStream_t stream); + void calculatePotential(); + void calculatePotential(cufftComplex *charge_potential); + Grid getGrid(); + +private: + Parameters parameters; + cudaStream_t cuda_stream; + cufftHandle plan_fft; + cufftHandle plan_ifft; + bool initialized; }; #ifdef __CUDACC__ -//extern __device__ __constant__ FdElectrostatics::Parameters fde_parameters_gpu; +// extern __device__ __constant__ FdElectrostatics::Parameters +// fde_parameters_gpu; __device__ cufftReal fde_getNode(int x, int y, int z); __device__ cufftReal fde_getNode(int i); @@ -72,5 +71,4 @@ __device__ void fde_setNode(int i, cufftReal value); #endif //__CUDACC__ - #endif diff --git a/src/core/fene.cpp b/src/core/fene.cpp index 0d427d4c45..ef5a6a3502 100755 --- a/src/core/fene.cpp +++ b/src/core/fene.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file fene.cpp * @@ -27,9 +27,8 @@ #include "communication.hpp" /// set the parameters for the fene potential -int fene_set_params(int bond_type, double k, double drmax, double r0) -{ - if(bond_type < 0) +int fene_set_params(int bond_type, double k, double drmax, double r0) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -38,14 +37,16 @@ int fene_set_params(int bond_type, double k, double drmax, double r0) bonded_ia_params[bond_type].p.fene.drmax = drmax; bonded_ia_params[bond_type].p.fene.r0 = r0; - bonded_ia_params[bond_type].p.fene.drmax2 = Utils::sqr(bonded_ia_params[bond_type].p.fene.drmax); - bonded_ia_params[bond_type].p.fene.drmax2i = 1.0/bonded_ia_params[bond_type].p.fene.drmax2; + bonded_ia_params[bond_type].p.fene.drmax2 = + Utils::sqr(bonded_ia_params[bond_type].p.fene.drmax); + bonded_ia_params[bond_type].p.fene.drmax2i = + 1.0 / bonded_ia_params[bond_type].p.fene.drmax2; bonded_ia_params[bond_type].type = BONDED_IA_FENE; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); - + mpi_bcast_ia_params(bond_type, -1); + return ES_OK; } diff --git a/src/core/fene.hpp b/src/core/fene.hpp index 7e1fd7ca3e..1ddb3a005d 100755 --- a/src/core/fene.hpp +++ b/src/core/fene.hpp @@ -1,37 +1,37 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _FENE_HPP #define _FENE_HPP /** \file fene.hpp - * Routines to calculate the FENE Energy or/and FENE force + * Routines to calculate the FENE Energy or/and FENE force * for a particle pair. * \ref forces.cpp */ -#include "utils.hpp" +#include "debug.hpp" +#include "errorhandling.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" #include "random.hpp" -#include "errorhandling.hpp" -#include "debug.hpp" +#include "utils.hpp" /************************************************************/ @@ -39,62 +39,79 @@ int fene_set_params(int bond_type, double k, double drmax, double r0); /** Computes the FENE pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. - @param iaparams bond type number of the angle interaction (see \ref interaction_data.cpp). + @param iaparams bond type number of the angle interaction (see \ref + interaction_data.cpp). @param dx particle distance vector @param force returns force of particle 1 @return true if the bond is broken */ -inline int calc_fene_pair_force(Particle *p1, Particle *p2, - Bonded_ia_parameters *iaparams, - double dx[3], double force[3]) { +inline int calc_fene_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, double dx[3], + double force[3]) { int i; - + const double len2 = sqrlen(dx); const double len = sqrt(len2); const double dr = len - iaparams->p.fene.r0; - if (dr >= iaparams->p.fene.drmax) return 1; + if (dr >= iaparams->p.fene.drmax) + return 1; - double fac = -iaparams->p.fene.k * dr / ((1.0 - dr*dr*iaparams->p.fene.drmax2i)); + double fac = + -iaparams->p.fene.k * dr / ((1.0 - dr * dr * iaparams->p.fene.drmax2i)); if (fabs(dr) > ROUND_ERROR_PREC) { - if(len > ROUND_ERROR_PREC) { /* Regular case */ - fac /= len; - } else { /* dx[] == 0: the force is undefined. Let's use a random direction */ - for(int i = 0;i < 3;i++) dx[i] = d_random()-0.5; - fac /= sqrt(sqrlen(dx)); - } - } else { + if (len > ROUND_ERROR_PREC) { /* Regular case */ + fac /= len; + } else { /* dx[] == 0: the force is undefined. Let's use a random direction + */ + for (int i = 0; i < 3; i++) + dx[i] = d_random() - 0.5; + fac /= sqrt(sqrlen(dx)); + } + } else { fac = 0.0; } - - FENE_TRACE(if(fac > 50) fprintf(stderr,"WARNING: FENE force factor between Pair (%d,%d) large: %f at distance %f\n", p1->p.identity,p2->p.identity,fac,sqrt(len2)) ); - - for(i=0;i<3;i++) - force[i] = fac*dx[i]; - - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: FENE f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,sqrt(len2),fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: FENE f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,sqrt(len2),fac)); - + + FENE_TRACE(if (fac > 50) + fprintf(stderr, "WARNING: FENE force factor between Pair " + "(%d,%d) large: %f at distance %f\n", + p1->p.identity, p2->p.identity, fac, sqrt(len2))); + + for (i = 0; i < 3; i++) + force[i] = fac * dx[i]; + + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: FENE f = (%.3e,%.3e,%.3e) with " + "part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, sqrt(len2), fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: FENE f = (%.3e,%.3e,%.3e) with " + "part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, sqrt(len2), fac)); + return 0; } -inline int fene_pair_energy(Particle *p1, Particle *p2, - Bonded_ia_parameters *iaparams, - double dx[3], double *_energy) { +inline int fene_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, double dx[3], + double *_energy) { /* compute bond stretching (r-r0) */ - double dr = sqrt(sqrlen(dx))-iaparams->p.fene.r0; + double dr = sqrt(sqrlen(dx)) - iaparams->p.fene.r0; /* check bond stretching */ - if(dr >= iaparams->p.fene.drmax) { - runtimeErrorMsg() <<"FENE bond broken between particles "<< p1->p.identity << " and " << p2->p.identity; + if (dr >= iaparams->p.fene.drmax) { + runtimeErrorMsg() << "FENE bond broken between particles " << p1->p.identity + << " and " << p2->p.identity; return 1; } - double energy = -0.5*iaparams->p.fene.k*iaparams->p.fene.drmax2; - energy *= log((1.0 - dr*dr*iaparams->p.fene.drmax2i)); + double energy = -0.5 * iaparams->p.fene.k * iaparams->p.fene.drmax2; + energy *= log((1.0 - dr * dr * iaparams->p.fene.drmax2i)); *_energy = energy; return 0; } diff --git a/src/core/fft-common.cpp b/src/core/fft-common.cpp index 3fd065f4b1..373da3fb54 100755 --- a/src/core/fft-common.cpp +++ b/src/core/fft-common.cpp @@ -1,26 +1,27 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file fft-common.cpp * - * Routines, row decomposition, data structures and communication for the 3D-FFT. + * Routines, row decomposition, data structures and communication for the + * 3D-FFT. * */ #include "fft-common.hpp" @@ -31,18 +32,17 @@ #include #include -#include "utils.hpp" #include "communication.hpp" #include "debug.hpp" +#include "utils.hpp" -void fft_common_pre_init(fft_data_struct *fft) -{ - for(int i=0;i<4;i++) { - fft->plan[i].group = (int*)Utils::malloc(1*n_nodes*sizeof(int)); +void fft_common_pre_init(fft_data_struct *fft) { + for (int i = 0; i < 4; i++) { + fft->plan[i].group = (int *)Utils::malloc(1 * n_nodes * sizeof(int)); fft->plan[i].send_block = nullptr; - fft->plan[i].send_size = nullptr; + fft->plan[i].send_size = nullptr; fft->plan[i].recv_block = nullptr; - fft->plan[i].recv_size = nullptr; + fft->plan[i].recv_size = nullptr; } fft->init_tag = 0; @@ -53,145 +53,141 @@ void fft_common_pre_init(fft_data_struct *fft) fft->data_buf = nullptr; } -void fft_pack_block(double *in, double *out, int start[3], int size[3], int dim[3], int element) -{ +void fft_pack_block(double *in, double *out, int start[3], int size[3], + int dim[3], int element) { /* mid and slow changing indices */ - int m,s; + int m, s; /* linear index of in grid, linear index of out grid */ - int li_in,li_out=0; + int li_in, li_out = 0; /* copy size */ int copy_size; /* offsets for indizes in input grid */ - int m_in_offset,s_in_offset; + int m_in_offset, s_in_offset; /* offsets for indizes in output grid */ int m_out_offset; - copy_size = element * size[2] * sizeof(double); - m_in_offset = element * dim[2]; - s_in_offset = element * (dim[2] * (dim[1] - size[1])); + copy_size = element * size[2] * sizeof(double); + m_in_offset = element * dim[2]; + s_in_offset = element * (dim[2] * (dim[1] - size[1])); m_out_offset = element * size[2]; - li_in = element * (start[2]+dim[2]*(start[1]+dim[1]*start[0])); + li_in = element * (start[2] + dim[2] * (start[1] + dim[1] * start[0])); - for(s=0 ;s0 ) { - n=group[g_size-1]; - for(i=g_size-1; i>0; i--) group[i] = group[i-1]; + while (c_pos > 0) { + n = group[g_size - 1]; + for (i = g_size - 1; i > 0; i--) + group[i] = group[i - 1]; group[0] = n; c_pos--; } return g_size; } -int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], double mesh_off[3], - int loc_mesh[3], int start[3]) -{ - int i, last[3], size=1; - - for(i=0;i<3;i++) { - start[i] = (int)ceil( (mesh[i]/(double)n_grid[i])*n_pos[i] - mesh_off[i] ); - last[i] = (int)floor((mesh[i]/(double)n_grid[i])*(n_pos[i]+1) - mesh_off[i] ); +int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], + double mesh_off[3], int loc_mesh[3], int start[3]) { + int i, last[3], size = 1; + + for (i = 0; i < 3; i++) { + start[i] = + (int)ceil((mesh[i] / (double)n_grid[i]) * n_pos[i] - mesh_off[i]); + last[i] = (int)floor((mesh[i] / (double)n_grid[i]) * (n_pos[i] + 1) - + mesh_off[i]); /* correct round off errors */ - if( (mesh[i]/(double)n_grid[i])*(n_pos[i]+1) - mesh_off[i] - last[i] < 1.0e-15 ) last[i]--; - if(1.0+ (mesh[i]/(double)n_grid[i])*n_pos[i]-mesh_off[i]-start[i] < 1.0e-15 ) start[i]--; - loc_mesh[i] = last[i]-start[i]+1; + if ((mesh[i] / (double)n_grid[i]) * (n_pos[i] + 1) - mesh_off[i] - last[i] < + 1.0e-15) + last[i]--; + if (1.0 + (mesh[i] / (double)n_grid[i]) * n_pos[i] - mesh_off[i] - + start[i] < + 1.0e-15) + start[i]--; + loc_mesh[i] = last[i] - start[i] + 1; size *= loc_mesh[i]; } return size; } - -int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], - int mesh[3], double mesh_off[3], int block[6]) -{ - int i,size=1; +int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], + int mesh[3], double mesh_off[3], int block[6]) { + int i, size = 1; int mesh1[3], first1[3], last1[3]; int mesh2[3], first2[3], last2[3]; fft_calc_local_mesh(pos1, grid1, mesh, mesh_off, mesh1, first1); fft_calc_local_mesh(pos2, grid2, mesh, mesh_off, mesh2, first2); - for(i=0;i<3;i++) { - last1[i] = first1[i] + mesh1[i] -1; - last2[i] = first2[i] + mesh2[i] -1; - block[i ] = std::max(first1[i],first2[i]) - first1[i]; - block[i+3] = (std::min(last1[i], last2[i] ) - first1[i])-block[i]+1; - size *= block[i+3]; + for (i = 0; i < 3; i++) { + last1[i] = first1[i] + mesh1[i] - 1; + last2[i] = first2[i] + mesh2[i] - 1; + block[i] = std::max(first1[i], first2[i]) - first1[i]; + block[i + 3] = (std::min(last1[i], last2[i]) - first1[i]) - block[i] + 1; + size *= block[i + 3]; } return size; } -void fft_print_fft_plan(fft_forw_plan pl) -{ +void fft_print_fft_plan(fft_forw_plan pl) { int i; - fprintf(stderr,"%d: dir=%d, row_dir=%d, n_permute=%d, n_ffts=%d\n", - this_node, pl.dir, pl.row_dir, pl.n_permute, pl.n_ffts); - - fprintf(stderr,"%d: local: old_mesh=(%d,%d,%d), new_mesh=(%d,%d,%d), start=(%d,%d,%d)\n",this_node, - pl.old_mesh[0], pl.old_mesh[1], pl.old_mesh[2], - pl.new_mesh[0], pl.new_mesh[1], pl.new_mesh[2], - pl.start[0], pl.start[1], pl.start[2]); - - fprintf(stderr,"%d: g_size=%d group=(",this_node,pl.g_size); - for(i=0;i 7) { - block1=b; - divide = (int)ceil(mesh/(double)block1); + while (divide == 0) { + if (b * mesh > 7) { + block1 = b; + divide = (int)ceil(mesh / (double)block1); } b++; } - for(b=0;b=0; i0--) { - for(i1=start1; i1=st[0] && i0=st[1] && - i1=st[2] && i21.0e-15) { - if(tmp<0) fprintf(stderr,"%1.2e",tmp); - else fprintf(stderr," %1.2e",tmp); - } - else { - fprintf(stderr," %1.2e",0.0); - } - } - MPI_Barrier(comm_cart); - } - if(my==1) fprintf(stderr," | "); + for (b = 0; b < divide; b++) { + start1 = b * block1; + for (i0 = mesh - 1; i0 >= 0; i0--) { + for (i1 = start1; i1 < std::min(start1 + block1, mesh); i1++) { + for (i2 = 0; i2 < mesh; i2++) { + if (i0 >= st[0] && i0 < en[0] && i1 >= st[1] && i1 < en[1] && + i2 >= st[2] && i2 < en[2]) + my = 1; + else + my = 0; + MPI_Barrier(comm_cart); + if (my == 1) { + + tmp = data[num + (element * + ((i2 - st[2]) + + si[2] * ((i1 - st[1]) + si[1] * (i0 - st[0]))))]; + if (fabs(tmp) > 1.0e-15) { + if (tmp < 0) + fprintf(stderr, "%1.2e", tmp); + else + fprintf(stderr, " %1.2e", tmp); + } else { + fprintf(stderr, " %1.2e", 0.0); + } + } + MPI_Barrier(comm_cart); + } + if (my == 1) + fprintf(stderr, " | "); } - if(my==1) fprintf(stderr,"\n"); + if (my == 1) + fprintf(stderr, "\n"); } - if(my==1) fprintf(stderr,"\n"); + if (my == 1) + fprintf(stderr, "\n"); } - } - #endif /* defined(P3M) || defined(DP3M) */ diff --git a/src/core/fft-common.hpp b/src/core/fft-common.hpp index 78b9c4985f..037c675e76 100755 --- a/src/core/fft-common.hpp +++ b/src/core/fft-common.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _FFT_COMMON_H #define _FFT_COMMON_H @@ -30,10 +30,10 @@ * data types ************************************************/ -/** Structure for performing a 1D FFT. +/** Structure for performing a 1D FFT. * * This includes the information about the redistribution of the 3D - * FFT *grid before the actual FFT. + * FFT *grid before the actual FFT. */ typedef struct { /** plan direction: 0 = Forward FFT, 1 = Backward FFT. */ @@ -42,7 +42,7 @@ typedef struct { int row_dir; /** permutations from normal coordinate system. */ int n_permute; - /** number of 1D FFTs. */ + /** number of 1D FFTs. */ int n_ffts; /** plan for fft. */ fftw_plan our_fftw_plan; @@ -58,20 +58,20 @@ typedef struct { /** size of new mesh (number of mesh points). */ int new_size; - /** number of nodes which have to communicate with each other. */ + /** number of nodes which have to communicate with each other. */ int g_size; - /** group of nodes which have to communicate with each other. */ + /** group of nodes which have to communicate with each other. */ int *group; /** packing function for send blocks. */ - void (*pack_function)(double*, double*, int*, int*, int*, int); - /** Send block specification. 6 integers for each node: start[3], size[3]. */ + void (*pack_function)(double *, double *, int *, int *, int *, int); + /** Send block specification. 6 integers for each node: start[3], size[3]. */ int *send_block; - /** Send block communication sizes. */ + /** Send block communication sizes. */ int *send_size; - /** Recv block specification. 6 integers for each node: start[3], size[3]. */ + /** Recv block specification. 6 integers for each node: start[3], size[3]. */ int *recv_block; - /** Recv block communication sizes. */ + /** Recv block communication sizes. */ int *recv_size; /** size of send block elements. */ int element; @@ -87,7 +87,7 @@ typedef struct { void (*fft_function)(fftw_plan); /** packing function for send blocks. */ - void (*pack_function)(double*, double*, int*, int*, int*, int); + void (*pack_function)(double *, double *, int *, int *, int *, int); } fft_back_plan; typedef struct { @@ -124,13 +124,13 @@ typedef struct { /* MPI tags for the fft communications: */ /** Tag for communication in fft_init() */ -#define REQ_FFT_INIT 300 +#define REQ_FFT_INIT 300 /** Tag for communication in forw_grid_comm() */ -#define REQ_FFT_FORW 301 +#define REQ_FFT_FORW 301 /** Tag for communication in back_grid_comm() */ -#define REQ_FFT_BACK 302 +#define REQ_FFT_BACK 302 /* Tag for wisdom file I/O */ -# define FFTW_FAILURE 0 +#define FFTW_FAILURE 0 /** Initialize FFT data structure. */ void fft_common_pre_init(fft_data_struct *fft); @@ -154,13 +154,13 @@ void fft_common_pre_init(fft_data_struct *fft); * \param grid2 The node grid you want to have (Input). * \param node_list1 Linear node index list for grid1 (Input). * \param node_list2 Linear node index list for grid2 (Output). - * \param group communication group (node identity list) for the calling node (Output). + * \param group communication group (node identity list) for the calling + * node (Output). * \param pos positions of the nodes in in grid2 (Output). * \param my_pos position of this_node in grid2. * \return Size of the communication group (Output of course!). */ -int fft_find_comm_groups(int grid1[3], int grid2[3], int *node_list1, int *node_list2, - int *group, int *pos, int *my_pos); - +int fft_find_comm_groups(int grid1[3], int grid2[3], int *node_list1, + int *node_list2, int *group, int *pos, int *my_pos); /** Calculate the local fft mesh. Calculate the local mesh (loc_mesh) * of a node at position (n_pos) in a node grid (n_grid) for a global @@ -175,8 +175,8 @@ int fft_find_comm_groups(int grid1[3], int grid2[3], int *node_list1, int *node_ * \param loc_mesh local mesh dimension (output). * \param start first point of local mesh in global mesh (output). */ -int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], double mesh_off[3], - int loc_mesh[3], int start[3]); +int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], + double mesh_off[3], int loc_mesh[3], int start[3]); /** Calculate a send (or recv.) block for grid communication during a * decomposition change. Calculate the send block specification @@ -187,10 +187,12 @@ int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], double mesh_of * via its size (mesh) and its mesh offset (mesh_off (in mesh * units)). * - * For the calculation of a receive block you have to change the arguments in the following way:
+ * For the calculation of a receive block you have to change the arguments in + * the following way:
* pos1 - position of receiving node in the desired node grid.
* grid1 - desired node grid.
- * pos2 - position of the node you intend to receive the data from in the actual node grid.
+ * pos2 - position of the node you intend to receive the data from in the + * actual node grid.
* grid2 - actual node grid.
* * \return size of the send block. @@ -202,9 +204,8 @@ int fft_calc_local_mesh(int n_pos[3], int n_grid[3], int mesh[3], double mesh_of * \param mesh_off global mesh offset (see \ref p3m_data_struct). * \param block send block specification. */ -int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], - int mesh[3], double mesh_off[3], int block[6]); - +int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], + int mesh[3], double mesh_off[3], int block[6]); /** pack a block (size[3] starting at start[3]) of an input 3d-grid * with dimension dim[3] into an output 3d-block with dimension size[3]. @@ -212,8 +213,8 @@ int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], * The block with dimensions (size[0], size[1], size[2]) is stored * in 'row-major-order' or 'C-order', that means the first index is * changing slowest when running through the linear array. The - * element (i0 (slow), i1 (mid), i2 (fast)) has the linear index - * li = i2 + size[2] * (i1 + (size[1]*i0)) + * element (i0 (slow), i1 (mid), i2 (fast)) has the linear index + * li = i2 + size[2] * (i1 + (size[1]*i0)) * * \param in pointer to input 3d-grid. * \param out pointer to output 3d-grid (block). @@ -222,22 +223,23 @@ int fft_calc_send_block(int pos1[3], int grid1[3], int pos2[3], int grid2[3], * \param dim size of the in-grid. * \param element size of a grid element (e.g. 1 for Real, 2 for Complex). */ -void fft_pack_block(double *in, double *out, int start[3], int size[3], - int dim[3], int element); +void fft_pack_block(double *in, double *out, int start[3], int size[3], + int dim[3], int element); /** pack a block with dimensions (size[0] * size[1] * aize[2]) starting * at start[3] of an input 3d-grid with dimension dim[3] into an * output 3d-grid with dimensions (size[2] * size[0] * size[1]) with * a simulatanous one-fold permutation of the indices. * - * The permutation is defined as: + * The permutation is defined as: * slow_in -> fast_out, mid_in ->slow_out, fast_in -> mid_out * - * An element (i0_in , i1_in , i2_in ) is then - * (i0_out = i1_in-start[1], i1_out = i2_in-start[2], i2_out = i0_in-start[0]) and + * An element (i0_in , i1_in , i2_in ) is then + * (i0_out = i1_in-start[1], i1_out = i2_in-start[2], i2_out = i0_in-start[0]) + * and * for the linear indices we have:
* li_in = i2_in + size[2] * (i1_in + (size[1]*i0_in))
- * li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out)) + * li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out)) * * For index definition see \ref fft_pack_block. * @@ -248,22 +250,23 @@ void fft_pack_block(double *in, double *out, int start[3], int size[3], * \param dim size of the in-grid. * \param element size of a grid element (e.g. 1 for Real, 2 for Complex). */ -void fft_pack_block_permute1(double *in, double *out, int start[3], int size[3], - int dim[3], int element); +void fft_pack_block_permute1(double *in, double *out, int start[3], int size[3], + int dim[3], int element); /** pack a block with dimensions (size[0] * size[1] * aize[2]) starting * at start[3] of an input 3d-grid with dimension dim[3] into an * output 3d-grid with dimensions (size[2] * size[0] * size[1]), this * is a simulatanous two-fold permutation of the indices. * - * The permutation is defined as: + * The permutation is defined as: * slow_in -> mid_out, mid_in ->fast_out, fast_in -> slow_out * - * An element (i0_in , i1_in , i2_in ) is then - * (i0_out = i2_in-start[2], i1_out = i0_in-start[0], i2_out = i1_in-start[1]) and + * An element (i0_in , i1_in , i2_in ) is then + * (i0_out = i2_in-start[2], i1_out = i0_in-start[0], i2_out = i1_in-start[1]) + * and * for the linear indices we have:
* li_in = i2_in + size[2] * (i1_in + (size[1]*i0_in))
- * li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out)) + * li_out = i2_out + size[0] * (i1_out + (size[2]*i0_out)) * * For index definition see \ref fft_pack_block. * @@ -274,9 +277,8 @@ void fft_pack_block_permute1(double *in, double *out, int start[3], int size[3], * \param dim size of the in-grid. * \param element size of a grid element (e.g. 1 for Real, 2 for Complex). */ -void fft_pack_block_permute2(double *in, double *out, int start[3], int size[3], - int dim[3],int element); - +void fft_pack_block_permute2(double *in, double *out, int start[3], int size[3], + int dim[3], int element); /** unpack a 3d-grid input block (size[3]) into an output 3d-grid * with dimension dim[3] at start position start[3]. @@ -290,23 +292,23 @@ void fft_pack_block_permute2(double *in, double *out, int start[3], int size[3], * \param dim size of the in-grid. * \param element size of a grid element (e.g. 1 for Real, 2 for Complex). */ -void fft_unpack_block(double *in, double *out, int start[3], int size[3], - int dim[3], int element); +void fft_unpack_block(double *in, double *out, int start[3], int size[3], + int dim[3], int element); -/** Debug function to print global fft mesh. - Print a globaly distributed mesh contained in data. Element size is element. +/** Debug function to print global fft mesh. + Print a globaly distributed mesh contained in data. Element size is element. * \param plan fft/communication plan (see \ref fft_forw_plan). * \param data mesh data. * \param element element size. * \param num element index to print. */ -void fft_print_global_fft_mesh(fft_forw_plan plan, double *data, int element, int num); +void fft_print_global_fft_mesh(fft_forw_plan plan, double *data, int element, + int num); -/** Debug function to print fft_forw_plan structure. +/** Debug function to print fft_forw_plan structure. * \param pl fft/communication plan (see \ref fft_forw_plan). */ void fft_print_fft_plan(fft_forw_plan pl); - #endif /* defined(P3M) || defined(DP3M) */ #endif /* _FFT_COMMON_H */ diff --git a/src/core/fft-dipolar.cpp b/src/core/fft-dipolar.cpp index 2d444c9e51..a5e9da3719 100755 --- a/src/core/fft-dipolar.cpp +++ b/src/core/fft-dipolar.cpp @@ -36,9 +36,9 @@ void *fftw_malloc(size_t n); #include #include "communication.hpp" +#include "debug.hpp" #include "fft-common.hpp" #include "grid.hpp" -#include "debug.hpp" /************************************************ * variables @@ -237,14 +237,13 @@ int dfft_init(double **data, int *local_mesh_dim, int *local_mesh_margin, } /* Factor 2 for complex numbers */ - dfft.send_buf = Utils::realloc(dfft.send_buf, - dfft.max_comm_size * sizeof(double)); - dfft.recv_buf = Utils::realloc(dfft.recv_buf, - dfft.max_comm_size * sizeof(double)); - (*data) = - Utils::realloc((*data), dfft.max_mesh_size * sizeof(double)); - dfft.data_buf = Utils::realloc(dfft.data_buf, - dfft.max_mesh_size * sizeof(double)); + dfft.send_buf = + Utils::realloc(dfft.send_buf, dfft.max_comm_size * sizeof(double)); + dfft.recv_buf = + Utils::realloc(dfft.recv_buf, dfft.max_comm_size * sizeof(double)); + (*data) = Utils::realloc((*data), dfft.max_mesh_size * sizeof(double)); + dfft.data_buf = + Utils::realloc(dfft.data_buf, dfft.max_mesh_size * sizeof(double)); if (!(*data) || !dfft.data_buf || !dfft.recv_buf || !dfft.send_buf) { fprintf(stderr, "%d: Could not allocate FFT data arays\n", this_node); errexit(); diff --git a/src/core/fft-dipolar.hpp b/src/core/fft-dipolar.hpp index eef1b01f2d..e78db72957 100755 --- a/src/core/fft-dipolar.hpp +++ b/src/core/fft-dipolar.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _FFT_MAGNETOSTATICS_H @@ -24,7 +24,8 @@ /** \file fft-dipolar.hpp * - * Routines, row decomposition, data structures and communication for the 3D-FFT. + * Routines, row decomposition, data structures and communication for the + * 3D-FFT. * * The 3D-FFT is split into 3 ond dimensional FFTs. The data is * distributed in such a way, that for the actual direction of the @@ -37,7 +38,8 @@ * sufficient) * * \todo Combine the forward and backward structures. - * \todo The packing routines could be moved to utils.hpp when they are needed elsewhere. + * \todo The packing routines could be moved to utils.hpp when they are needed + * elsewhere. */ #include "config.hpp" @@ -52,7 +54,7 @@ extern fft_data_struct dfft; /*@{*/ /** Initialize some arrays connected to the 3D-FFT. */ -void dfft_pre_init(); +void dfft_pre_init(); /** Initialize everything connected to the 3D-FFT related to the dipole-dipole. @@ -64,24 +66,23 @@ void dfft_pre_init(); * \param global_mesh_off Pointer to global CA mesh offset. * \param ks_pnum Pointer to number of permutations in k-space. */ -int dfft_init(double **data, - int *ca_mesh_dim, int *ca_mesh_margin, - int* global_mesh_dim, double *global_mesh_off, - int *ks_pnum); +int dfft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, + int *global_mesh_dim, double *global_mesh_off, int *ks_pnum); -/** perform the forward 3D FFT for meshes related to the magnetic dipole-dipole interaction. +/** perform the forward 3D FFT for meshes related to the magnetic dipole-dipole + interaction. The assigned charges are in \a data. The result is also stored in \a data. \warning The content of \a data is overwritten. \param data DMesh. */ void dfft_perform_forw(double *data); -/** perform the backward 3D FFT for meshes related to the magnetic dipole-dipole interaction. +/** perform the backward 3D FFT for meshes related to the magnetic dipole-dipole + interaction. \warning The content of \a data is overwritten. \param data DMesh. */ void dfft_perform_back(double *data); - #endif /* DP3M */ #endif /* _FFT_MAGNETOSTATICS_H */ diff --git a/src/core/fft.cpp b/src/core/fft.cpp index d379e2409f..dfa5a87704 100755 --- a/src/core/fft.cpp +++ b/src/core/fft.cpp @@ -1,26 +1,27 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file fft.cpp * - * Routines, row decomposition, data structures and communication for the 3D-FFT. + * Routines, row decomposition, data structures and communication for the + * 3D-FFT. * */ @@ -32,43 +33,39 @@ /* our remapping of malloc interferes with fftw3's name mangling. */ void *fftw_malloc(size_t n); -#include #include "communication.hpp" -#include "grid.hpp" -#include "fft-common.hpp" #include "debug.hpp" +#include "fft-common.hpp" +#include "grid.hpp" +#include /************************************************ * variables ************************************************/ fft_data_struct fft; -/** communicate the grid data according to the given fft_forw_plan. +/** communicate the grid data according to the given fft_forw_plan. * \param plan communication plan (see \ref fft_forw_plan). * \param in input mesh. * \param out output mesh. */ -static void -fft_forw_grid_comm(fft_forw_plan plan, double *in, double *out); +static void fft_forw_grid_comm(fft_forw_plan plan, double *in, double *out); -/** communicate the grid data according to the given fft_forw_plan/fft_bakc_plan. +/** communicate the grid data according to the given + * fft_forw_plan/fft_bakc_plan. * \param plan_f communication plan (see \ref fft_forw_plan). * \param plan_b additional back plan (see \ref fft_back_plan). * \param in input mesh. * \param out output mesh. */ -static void -fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b, double *in, double *out); +static void fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b, + double *in, double *out); -void fft_pre_init() { - fft_common_pre_init(&fft); -} +void fft_pre_init() { fft_common_pre_init(&fft); } -int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, - int* global_mesh_dim, double *global_mesh_off, - int *ks_pnum) -{ - int i,j; +int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, + int *global_mesh_dim, double *global_mesh_off, int *ks_pnum) { + int i, j; /* helpers */ int mult[3]; @@ -77,120 +74,134 @@ int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, int *n_id[4]; /* linear node identity lists for the node grids. */ int *n_pos[4]; /* positions of nodes in the node grids. */ - FFT_TRACE(fprintf(stderr,"%d: fft_init():\n",this_node)); - + FFT_TRACE(fprintf(stderr, "%d: fft_init():\n", this_node)); - fft.max_comm_size=0; fft.max_mesh_size=0; - for(i=0;i<4;i++) { - n_id[i] = (int*)Utils::malloc(1*n_nodes*sizeof(int)); - n_pos[i] = (int*)Utils::malloc(3*n_nodes*sizeof(int)); + fft.max_comm_size = 0; + fft.max_mesh_size = 0; + for (i = 0; i < 4; i++) { + n_id[i] = (int *)Utils::malloc(1 * n_nodes * sizeof(int)); + n_pos[i] = (int *)Utils::malloc(3 * n_nodes * sizeof(int)); } /* === node grids === */ /* real space node grid (n_grid[0]) */ - for(i=0;i<3;i++) { + for (i = 0; i < 3; i++) { n_grid[0][i] = node_grid[i]; my_pos[0][i] = node_pos[i]; } - for(i=0;i fft.max_comm_size) - fft.max_comm_size = fft.plan[i].send_size[j]; + fft.plan[i].send_size[j] = fft_calc_send_block( + my_pos[i - 1], n_grid[i - 1], &(n_pos[i][3 * node]), n_grid[i], + global_mesh_dim, global_mesh_off, &(fft.plan[i].send_block[6 * j])); + permute_ifield(&(fft.plan[i].send_block[6 * j]), 3, + -(fft.plan[i - 1].n_permute)); + permute_ifield(&(fft.plan[i].send_block[6 * j + 3]), 3, + -(fft.plan[i - 1].n_permute)); + if (fft.plan[i].send_size[j] > fft.max_comm_size) + fft.max_comm_size = fft.plan[i].send_size[j]; /* First plan send blocks have to be adjusted, since the CA grid - may have an additional margin outside the actual domain of the - node */ - if(i==1) { - for(int k=0;k<3;k++) - fft.plan[1].send_block[6*j+k ] += ca_mesh_margin[2*k]; + may have an additional margin outside the actual domain of the + node */ + if (i == 1) { + for (int k = 0; k < 3; k++) + fft.plan[1].send_block[6 * j + k] += ca_mesh_margin[2 * k]; } /* recv block: this_node from comm-group-node i (identity: node) */ - fft.plan[i].recv_size[j] - = fft_calc_send_block(my_pos[i], n_grid[i], &(n_pos[i-1][3*node]), n_grid[i-1], - global_mesh_dim, global_mesh_off, &(fft.plan[i].recv_block[6*j])); - permute_ifield(&(fft.plan[i].recv_block[6*j]),3,-(fft.plan[i].n_permute)); - permute_ifield(&(fft.plan[i].recv_block[6*j+3]),3,-(fft.plan[i].n_permute)); - if(fft.plan[i].recv_size[j] > fft.max_comm_size) - fft.max_comm_size = fft.plan[i].recv_size[j]; + fft.plan[i].recv_size[j] = fft_calc_send_block( + my_pos[i], n_grid[i], &(n_pos[i - 1][3 * node]), n_grid[i - 1], + global_mesh_dim, global_mesh_off, &(fft.plan[i].recv_block[6 * j])); + permute_ifield(&(fft.plan[i].recv_block[6 * j]), 3, + -(fft.plan[i].n_permute)); + permute_ifield(&(fft.plan[i].recv_block[6 * j + 3]), 3, + -(fft.plan[i].n_permute)); + if (fft.plan[i].recv_size[j] > fft.max_comm_size) + fft.max_comm_size = fft.plan[i].recv_size[j]; } - for(j=0;j<3;j++) fft.plan[i].old_mesh[j] = fft.plan[i-1].new_mesh[j]; - if(i==1) - fft.plan[i].element = 1; + for (j = 0; j < 3; j++) + fft.plan[i].old_mesh[j] = fft.plan[i - 1].new_mesh[j]; + if (i == 1) + fft.plan[i].element = 1; else { fft.plan[i].element = 2; - for(j=0; j fft.max_mesh_size) fft.max_mesh_size = 2*fft.plan[i].new_size; + fft.max_mesh_size = (ca_mesh_dim[0] * ca_mesh_dim[1] * ca_mesh_dim[2]); + for (i = 1; i < 4; i++) + if (2 * fft.plan[i].new_size > fft.max_mesh_size) + fft.max_mesh_size = 2 * fft.plan[i].new_size; - FFT_TRACE(fprintf(stderr,"%d: fft.max_comm_size = %d, fft.max_mesh_size = %d\n", - this_node,fft.max_comm_size,fft.max_mesh_size)); + FFT_TRACE(fprintf(stderr, + "%d: fft.max_comm_size = %d, fft.max_mesh_size = %d\n", + this_node, fft.max_comm_size, fft.max_mesh_size)); /* === pack function === */ - for(i=1;i<4;i++) { - fft.plan[i].pack_function = fft_pack_block_permute2; - FFT_TRACE(fprintf(stderr,"%d: forw plan[%d] permute 2 \n",this_node,i)); + for (i = 1; i < 4; i++) { + fft.plan[i].pack_function = fft_pack_block_permute2; + FFT_TRACE(fprintf(stderr, "%d: forw plan[%d] permute 2 \n", this_node, i)); } - (*ks_pnum)=6; - if(fft.plan[1].row_dir==2) { + (*ks_pnum) = 6; + if (fft.plan[1].row_dir == 2) { fft.plan[1].pack_function = fft_pack_block; - FFT_TRACE(fprintf(stderr,"%d: forw plan[%d] permute 0 \n",this_node,1)); - (*ks_pnum)=4; - } - else if(fft.plan[1].row_dir==1) { + FFT_TRACE(fprintf(stderr, "%d: forw plan[%d] permute 0 \n", this_node, 1)); + (*ks_pnum) = 4; + } else if (fft.plan[1].row_dir == 1) { fft.plan[1].pack_function = fft_pack_block_permute1; - FFT_TRACE(fprintf(stderr,"%d: forw plan[%d] permute 1 \n",this_node,1)); - (*ks_pnum)=5; + FFT_TRACE(fprintf(stderr, "%d: forw plan[%d] permute 1 \n", this_node, 1)); + (*ks_pnum) = 5; } - + /* Factor 2 for complex numbers */ - fft.send_buf = Utils::realloc(fft.send_buf, fft.max_comm_size*sizeof(double)); - fft.recv_buf = Utils::realloc(fft.recv_buf, fft.max_comm_size*sizeof(double)); - if (*data) fftw_free(*data); - (*data) = (double *)fftw_malloc(fft.max_mesh_size*sizeof(double)); - if (fft.data_buf) fftw_free(fft.data_buf); - fft.data_buf = (double *)fftw_malloc(fft.max_mesh_size*sizeof(double)); - if(!(*data) || !fft.data_buf) { - fprintf(stderr,"%d: Could not allocate FFT data arays\n",this_node); + fft.send_buf = + Utils::realloc(fft.send_buf, fft.max_comm_size * sizeof(double)); + fft.recv_buf = + Utils::realloc(fft.recv_buf, fft.max_comm_size * sizeof(double)); + if (*data) + fftw_free(*data); + (*data) = (double *)fftw_malloc(fft.max_mesh_size * sizeof(double)); + if (fft.data_buf) + fftw_free(fft.data_buf); + fft.data_buf = (double *)fftw_malloc(fft.max_mesh_size * sizeof(double)); + if (!(*data) || !fft.data_buf) { + fprintf(stderr, "%d: Could not allocate FFT data arays\n", this_node); errexit(); } - fftw_complex *c_data = (fftw_complex *) (*data); + fftw_complex *c_data = (fftw_complex *)(*data); /* === FFT Routines (Using FFTW / RFFTW package)=== */ - for(i=1;i<4;i++) { - fft.plan[i].dir = FFTW_FORWARD; - /* FFT plan creation. - Attention: destroys contents of c_data/data and c_fft.data_buf/data_buf. */ - - if(fft.init_tag==1) fftw_destroy_plan(fft.plan[i].our_fftw_plan); - fft.plan[i].our_fftw_plan = - fftw_plan_many_dft(1,&fft.plan[i].new_mesh[2],fft.plan[i].n_ffts, - c_data,nullptr,1,fft.plan[i].new_mesh[2], - c_data,nullptr,1,fft.plan[i].new_mesh[2], - fft.plan[i].dir,FFTW_PATIENT); - - fft.plan[i].fft_function = fftw_execute; + for (i = 1; i < 4; i++) { + fft.plan[i].dir = FFTW_FORWARD; + /* FFT plan creation. + Attention: destroys contents of c_data/data and c_fft.data_buf/data_buf. + */ + + if (fft.init_tag == 1) + fftw_destroy_plan(fft.plan[i].our_fftw_plan); + fft.plan[i].our_fftw_plan = fftw_plan_many_dft( + 1, &fft.plan[i].new_mesh[2], fft.plan[i].n_ffts, c_data, nullptr, 1, + fft.plan[i].new_mesh[2], c_data, nullptr, 1, fft.plan[i].new_mesh[2], + fft.plan[i].dir, FFTW_PATIENT); + + fft.plan[i].fft_function = fftw_execute; } /* === The BACK Direction === */ /* this is needed because slightly different functions are used */ - for(i=1;i<4;i++) { + for (i = 1; i < 4; i++) { fft.back[i].dir = FFTW_BACKWARD; - if(fft.init_tag==1) fftw_destroy_plan(fft.back[i].our_fftw_plan); - fft.back[i].our_fftw_plan = - fftw_plan_many_dft(1,&fft.plan[i].new_mesh[2],fft.plan[i].n_ffts, - c_data,nullptr,1,fft.plan[i].new_mesh[2], - c_data,nullptr,1,fft.plan[i].new_mesh[2], - fft.back[i].dir,FFTW_PATIENT); + if (fft.init_tag == 1) + fftw_destroy_plan(fft.back[i].our_fftw_plan); + fft.back[i].our_fftw_plan = fftw_plan_many_dft( + 1, &fft.plan[i].new_mesh[2], fft.plan[i].n_ffts, c_data, nullptr, 1, + fft.plan[i].new_mesh[2], c_data, nullptr, 1, fft.plan[i].new_mesh[2], + fft.back[i].dir, FFTW_PATIENT); fft.back[i].fft_function = fftw_execute; fft.back[i].pack_function = fft_pack_block_permute1; - FFT_TRACE(fprintf(stderr,"%d: back plan[%d] permute 1 \n",this_node,i)); + FFT_TRACE(fprintf(stderr, "%d: back plan[%d] permute 1 \n", this_node, i)); } - if(fft.plan[1].row_dir==2) { + if (fft.plan[1].row_dir == 2) { fft.back[1].pack_function = fft_pack_block; - FFT_TRACE(fprintf(stderr,"%d: back plan[%d] permute 0 \n",this_node,1)); - } - else if(fft.plan[1].row_dir==1) { + FFT_TRACE(fprintf(stderr, "%d: back plan[%d] permute 0 \n", this_node, 1)); + } else if (fft.plan[1].row_dir == 1) { fft.back[1].pack_function = fft_pack_block_permute2; - FFT_TRACE(fprintf(stderr,"%d: back plan[%d] permute 2 \n",this_node,1)); + FFT_TRACE(fprintf(stderr, "%d: back plan[%d] permute 2 \n", this_node, 1)); } - fft.init_tag=1; + fft.init_tag = 1; /* free(data); */ - for(i=0;i<4;i++) { free(n_id[i]); free(n_pos[i]); } - return fft.max_mesh_size; + for (i = 0; i < 4; i++) { + free(n_id[i]); + free(n_pos[i]); + } + return fft.max_mesh_size; } -void fft_perform_forw(double *data) -{ +void fft_perform_forw(double *data) { int i; /* int m,n,o; */ /* ===== first direction ===== */ - FFT_TRACE(fprintf(stderr,"%d: fft_perform_forw: dir 1:\n",this_node)); + FFT_TRACE(fprintf(stderr, "%d: fft_perform_forw: dir 1:\n", this_node)); - fftw_complex *c_data = (fftw_complex *) data; - fftw_complex *c_data_buf = (fftw_complex *) fft.data_buf; + fftw_complex *c_data = (fftw_complex *)data; + fftw_complex *c_data_buf = (fftw_complex *)fft.data_buf; /* communication to current dir row format (in is data) */ fft_forw_grid_comm(fft.plan[1], data, fft.data_buf); - /* fprintf(stderr,"%d: start grid \n",this_node); i=0; @@ -312,105 +329,104 @@ void fft_perform_forw(double *data) */ /* complexify the real data array (in is fft.data_buf) */ - for(i=0;i1e-5)) { - printf("Complex value is not zero (i=%d,data=%g)!!!\n",i,data[2*i+1]); - if (i>100) errexit(); - } + for (i = 0; i < fft.plan[1].new_size; i++) { + fft.data_buf[i] = data[2 * i]; /* real value */ + // Vincent: + if (check_complex && (data[2 * i + 1] > 1e-5)) { + printf("Complex value is not zero (i=%d,data=%g)!!!\n", i, + data[2 * i + 1]); + if (i > 100) + errexit(); + } } /* communicate (in is fft.data_buf) */ - fft_back_grid_comm(fft.plan[1],fft.back[1],fft.data_buf,data); + fft_back_grid_comm(fft.plan[1], fft.back[1], fft.data_buf, data); /* REMARK: Result has to be in data. */ } -void fft_forw_grid_comm(fft_forw_plan plan, double *in, double *out) -{ +void fft_forw_grid_comm(fft_forw_plan plan, double *in, double *out) { int i; MPI_Status status; double *tmp_ptr; - for(i=0;ithis_node) { /* receive first, send second */ - MPI_Recv(fft.recv_buf, plan.recv_size[i], MPI_DOUBLE, - plan.group[i], REQ_FFT_FORW, comm_cart, &status); - MPI_Send(fft.send_buf, plan.send_size[i], MPI_DOUBLE, - plan.group[i], REQ_FFT_FORW, comm_cart); - } - else { /* Self communication... */ - tmp_ptr = fft.send_buf; + for (i = 0; i < plan.g_size; i++) { + plan.pack_function(in, fft.send_buf, &(plan.send_block[6 * i]), + &(plan.send_block[6 * i + 3]), plan.old_mesh, + plan.element); + + if (plan.group[i] < this_node) { /* send first, receive second */ + MPI_Send(fft.send_buf, plan.send_size[i], MPI_DOUBLE, plan.group[i], + REQ_FFT_FORW, comm_cart); + MPI_Recv(fft.recv_buf, plan.recv_size[i], MPI_DOUBLE, plan.group[i], + REQ_FFT_FORW, comm_cart, &status); + } else if (plan.group[i] > this_node) { /* receive first, send second */ + MPI_Recv(fft.recv_buf, plan.recv_size[i], MPI_DOUBLE, plan.group[i], + REQ_FFT_FORW, comm_cart, &status); + MPI_Send(fft.send_buf, plan.send_size[i], MPI_DOUBLE, plan.group[i], + REQ_FFT_FORW, comm_cart); + } else { /* Self communication... */ + tmp_ptr = fft.send_buf; fft.send_buf = fft.recv_buf; fft.recv_buf = tmp_ptr; } - fft_unpack_block(fft.recv_buf, out, &(plan.recv_block[6*i]), - &(plan.recv_block[6*i+3]), plan.new_mesh, plan.element); + fft_unpack_block(fft.recv_buf, out, &(plan.recv_block[6 * i]), + &(plan.recv_block[6 * i + 3]), plan.new_mesh, + plan.element); } } -void fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b, double *in, double *out) -{ +void fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b, double *in, + double *out) { int i; MPI_Status status; double *tmp_ptr; @@ -419,30 +435,30 @@ void fft_back_grid_comm(fft_forw_plan plan_f, fft_back_plan plan_b, double *in, replace the recieve blocks by the send blocks and vice versa. Attention then also new_mesh and old_mesh are exchanged */ - for(i=0;ithis_node) { /* receive first, send second */ - MPI_Recv(fft.recv_buf, plan_f.send_size[i], MPI_DOUBLE, - plan_f.group[i], REQ_FFT_BACK, comm_cart, &status); - MPI_Send(fft.send_buf, plan_f.recv_size[i], MPI_DOUBLE, - plan_f.group[i], REQ_FFT_BACK, comm_cart); - } - else { /* Self communication... */ - tmp_ptr = fft.send_buf; + for (i = 0; i < plan_f.g_size; i++) { + + plan_b.pack_function(in, fft.send_buf, &(plan_f.recv_block[6 * i]), + &(plan_f.recv_block[6 * i + 3]), plan_f.new_mesh, + plan_f.element); + + if (plan_f.group[i] < this_node) { /* send first, receive second */ + MPI_Send(fft.send_buf, plan_f.recv_size[i], MPI_DOUBLE, plan_f.group[i], + REQ_FFT_BACK, comm_cart); + MPI_Recv(fft.recv_buf, plan_f.send_size[i], MPI_DOUBLE, plan_f.group[i], + REQ_FFT_BACK, comm_cart, &status); + } else if (plan_f.group[i] > this_node) { /* receive first, send second */ + MPI_Recv(fft.recv_buf, plan_f.send_size[i], MPI_DOUBLE, plan_f.group[i], + REQ_FFT_BACK, comm_cart, &status); + MPI_Send(fft.send_buf, plan_f.recv_size[i], MPI_DOUBLE, plan_f.group[i], + REQ_FFT_BACK, comm_cart); + } else { /* Self communication... */ + tmp_ptr = fft.send_buf; fft.send_buf = fft.recv_buf; fft.recv_buf = tmp_ptr; } - fft_unpack_block(fft.recv_buf, out, &(plan_f.send_block[6*i]), - &(plan_f.send_block[6*i+3]), plan_f.old_mesh, plan_f.element); + fft_unpack_block(fft.recv_buf, out, &(plan_f.send_block[6 * i]), + &(plan_f.send_block[6 * i + 3]), plan_f.old_mesh, + plan_f.element); } } diff --git a/src/core/fft.hpp b/src/core/fft.hpp index 6742474a71..979a7fdb3f 100755 --- a/src/core/fft.hpp +++ b/src/core/fft.hpp @@ -1,28 +1,29 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _FFT_H #define _FFT_H /** \file fft.hpp * - * Routines, row decomposition, data structures and communication for the 3D-FFT. + * Routines, row decomposition, data structures and communication for the + * 3D-FFT. * * The 3D-FFT is split into 3 ond dimensional FFTs. The data is * distributed in such a way, that for the actual direction of the @@ -35,9 +36,10 @@ * sufficient) * * \todo Combine the forward and backward structures. - * \todo The packing routines could be moved to utils.hpp when they are needed elsewhere. + * \todo The packing routines could be moved to utils.hpp when they are needed + * elsewhere. * - * For more information about FFT usage, see \ref fft.cpp "fft.c". + * For more information about FFT usage, see \ref fft.cpp "fft.c". */ #include "config.hpp" @@ -65,8 +67,7 @@ void fft_pre_init(); * \param ks_pnum Pointer to number of permutations in k-space. */ int fft_init(double **data, int *ca_mesh_dim, int *ca_mesh_margin, - int* global_mesh_dim, double *global_mesh_off, - int *ks_pnum); + int *global_mesh_dim, double *global_mesh_off, int *ks_pnum); /** perform the forward 3D FFT. The assigned charges are in \a data. The result is also stored in \a data. diff --git a/src/core/field_coupling/couplings/Scaled.hpp b/src/core/field_coupling/couplings/Scaled.hpp index 75fa90342a..1561447b18 100644 --- a/src/core/field_coupling/couplings/Scaled.hpp +++ b/src/core/field_coupling/couplings/Scaled.hpp @@ -19,7 +19,9 @@ class Scaled { double &default_scale() { return m_default; } double const &default_scale() const { return m_default; } std::unordered_map &particle_scales() { return m_scales; } - std::unordered_map const &particle_scales() const { return m_scales; } + std::unordered_map const &particle_scales() const { + return m_scales; + } private: template double scale(Particle const &p) const { diff --git a/src/core/forcecap.cpp b/src/core/forcecap.cpp index dee4620a80..905060c95e 100755 --- a/src/core/forcecap.cpp +++ b/src/core/forcecap.cpp @@ -24,8 +24,8 @@ */ #include "forcecap.hpp" -#include "utils.hpp" #include "global.hpp" +#include "utils.hpp" double force_cap = 0.0; @@ -34,9 +34,7 @@ void forcecap_set(double forcecap) { mpi_bcast_parameter(FIELD_FORCE_CAP); } -double forcecap_get() { - return force_cap; -} +double forcecap_get() { return force_cap; } void forcecap_cap(ParticleRange particles) { if (force_cap <= 0) { diff --git a/src/core/forces.cpp b/src/core/forces.cpp index 48fa04ea56..4258bffd1c 100755 --- a/src/core/forces.cpp +++ b/src/core/forces.cpp @@ -32,11 +32,11 @@ #include "forcecap.hpp" #include "forces_inline.hpp" #include "iccp3m.hpp" +#include "immersed_boundaries.hpp" +#include "lb.hpp" #include "maggs.hpp" #include "p3m_gpu.hpp" #include "short_range_loop.hpp" -#include "immersed_boundaries.hpp" -#include "lb.hpp" #include diff --git a/src/core/forces.hpp b/src/core/forces.hpp index 027c3c0dbb..ec899b267b 100755 --- a/src/core/forces.hpp +++ b/src/core/forces.hpp @@ -1,28 +1,29 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef CORE_FORCES_HPP #define CORE_FORCES_HPP -/** \file forces.hpp Force calculation. +/** \file forces.hpp Force calculation. * - * \todo Preprocessor switches for all forces (Default: everything is turned on). + * \todo Preprocessor switches for all forces (Default: everything is turned + * on). * \todo Implement more flexible thermostat, %e.g. which thermostat to use. * * For more information see forces.cpp . @@ -74,7 +75,7 @@ void init_forces_ghosts(); */ void force_calc(); -/** Check if forces are NAN +/** Check if forces are NAN */ void check_forces(); diff --git a/src/core/forces_inline.hpp b/src/core/forces_inline.hpp index 3700498fe2..ea28041ec5 100644 --- a/src/core/forces_inline.hpp +++ b/src/core/forces_inline.hpp @@ -286,9 +286,9 @@ inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, double d[3], double torque2[3] = {0., 0., 0.}; int j; - /***********************************************/ - /* bond creation and breaking */ - /***********************************************/ +/***********************************************/ +/* bond creation and breaking */ +/***********************************************/ #ifdef COLLISION_DETECTION if (collision_params.mode != COLLISION_MODE_OFF) @@ -303,9 +303,9 @@ inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, double d[3], FORCE_TRACE(fprintf(stderr, "%d: interaction %d<->%d dist %f\n", this_node, p1->p.identity, p2->p.identity, dist)); - /***********************************************/ - /* non bonded pair potentials */ - /***********************************************/ +/***********************************************/ +/* non bonded pair potentials */ +/***********************************************/ #ifdef EXCLUSIONS if (do_nonbonded(p1, p2)) @@ -313,9 +313,9 @@ inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, double d[3], calc_non_bonded_pair_force(p1, p2, ia_params, d, dist, dist2, force.data(), torque1, torque2); - /***********************************************/ - /* short range electrostatics */ - /***********************************************/ +/***********************************************/ +/* short range electrostatics */ +/***********************************************/ #ifdef ELECTROSTATICS if (coulomb.method == COULOMB_DH) @@ -346,9 +346,9 @@ inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, double d[3], } #endif - /***********************************************/ - /* long range electrostatics */ - /***********************************************/ +/***********************************************/ +/* long range electrostatics */ +/***********************************************/ #ifdef ELECTROSTATICS /* real space coulomb */ @@ -404,9 +404,9 @@ inline void add_non_bonded_pair_force(Particle *p1, Particle *p2, double d[3], #endif /*ifdef ELECTROSTATICS */ - /***********************************************/ - /* long range magnetostatics */ - /***********************************************/ +/***********************************************/ +/* long range magnetostatics */ +/***********************************************/ #ifdef DIPOLES /* real space magnetic dipole-dipole */ @@ -483,10 +483,10 @@ inline void add_bonded_force(Particle *p1) { if (n_partners >= 2) { p3 = local_particles[p1->bl.e[i++]]; if (!p3) { - runtimeErrorMsg() - << "bond broken between particles " << p1->p.identity << ", " - << p1->bl.e[i - 2] << " and " << p1->bl.e[i - 1] - << " (particles are not stored on the same node)"; + runtimeErrorMsg() << "bond broken between particles " + << p1->p.identity << ", " << p1->bl.e[i - 2] + << " and " << p1->bl.e[i - 1] + << " (particles are not stored on the same node)"; return; } } @@ -495,10 +495,10 @@ inline void add_bonded_force(Particle *p1) { if (n_partners >= 3) { p4 = local_particles[p1->bl.e[i++]]; if (!p4) { - runtimeErrorMsg() - << "bond broken between particles " << p1->p.identity << ", " - << p1->bl.e[i - 3] << ", " << p1->bl.e[i - 2] << " and " - << p1->bl.e[i - 1] << " (particles not stored on the same node)"; + runtimeErrorMsg() << "bond broken between particles " + << p1->p.identity << ", " << p1->bl.e[i - 3] << ", " + << p1->bl.e[i - 2] << " and " << p1->bl.e[i - 1] + << " (particles not stored on the same node)"; return; } } @@ -689,10 +689,10 @@ inline void add_bonded_force(Particle *p1) { switch (n_partners) { case 1: if (bond_broken) { - runtimeErrorMsg() - << "bond broken between particles " << p1->p.identity << " and " - << p2->p.identity << ". Distance vector: " << dx[0] << " " - << dx[1] << " " << dx[2]; + runtimeErrorMsg() << "bond broken between particles " + << p1->p.identity << " and " << p2->p.identity + << ". Distance vector: " << dx[0] << " " << dx[1] + << " " << dx[2]; continue; } @@ -719,9 +719,9 @@ inline void add_bonded_force(Particle *p1) { break; case 2: if (bond_broken) { - runtimeErrorMsg() - << "bond broken between particles " << p1->p.identity << ", " - << p2->p.identity << " and " << p3->p.identity; + runtimeErrorMsg() << "bond broken between particles " + << p1->p.identity << ", " << p2->p.identity + << " and " << p3->p.identity; continue; } @@ -791,8 +791,6 @@ inline void check_particle_force(Particle *part) { #endif } -inline void add_single_particle_force(Particle *p) { - add_bonded_force(p); -} +inline void add_single_particle_force(Particle *p) { add_bonded_force(p); } #endif diff --git a/src/core/gaussian.cpp b/src/core/gaussian.cpp index 39fabd51bb..5d96f546b0 100755 --- a/src/core/gaussian.cpp +++ b/src/core/gaussian.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file gaussian.cpp * @@ -27,13 +27,13 @@ #ifdef GAUSSIAN -int gaussian_set_params(int part_type_a, int part_type_b, - double eps, double sig, double cut) -{ +int gaussian_set_params(int part_type_a, int part_type_b, double eps, + double sig, double cut) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) return ES_ERROR; - + + if (!data) + return ES_ERROR; + data->Gaussian_eps = eps; data->Gaussian_sig = sig; data->Gaussian_cut = cut; diff --git a/src/core/gaussian.hpp b/src/core/gaussian.hpp index 883f9e41f8..c9f9ae32d6 100755 --- a/src/core/gaussian.hpp +++ b/src/core/gaussian.hpp @@ -26,9 +26,9 @@ * for a particle pair. */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef GAUSSIAN diff --git a/src/core/gb.cpp b/src/core/gb.cpp index 856e00f2fa..c3022160d8 100755 --- a/src/core/gb.cpp +++ b/src/core/gb.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file gb.cpp * @@ -27,27 +27,28 @@ #ifdef GAY_BERNE -int gay_berne_set_params(int part_type_a, int part_type_b, - double eps, double sig, double cut, - double k1, double k2, - double mu, double nu) -{ +int gay_berne_set_params(int part_type_a, int part_type_b, double eps, + double sig, double cut, double k1, double k2, + double mu, double nu) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; + + data->GB_eps = eps; + data->GB_sig = sig; + data->GB_cut = cut; + data->GB_k1 = k1; + data->GB_k2 = k2; + data->GB_mu = mu; + data->GB_nu = nu; - data->GB_eps = eps; - data->GB_sig = sig; - data->GB_cut = cut; - data->GB_k1 = k1; - data->GB_k2 = k2; - data->GB_mu = mu; - data->GB_nu = nu; - /* Calculate dependent parameters */ - data->GB_chi1 = ((data->GB_k1*data->GB_k1) - 1) / ((data->GB_k1*data->GB_k1) + 1); - data->GB_chi2 = (pow(data->GB_k2,(1/data->GB_mu))-1)/(pow(data->GB_k2,(1/data->GB_mu))+1); + data->GB_chi1 = + ((data->GB_k1 * data->GB_k1) - 1) / ((data->GB_k1 * data->GB_k1) + 1); + data->GB_chi2 = (pow(data->GB_k2, (1 / data->GB_mu)) - 1) / + (pow(data->GB_k2, (1 / data->GB_mu)) + 1); /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); diff --git a/src/core/gb.hpp b/src/core/gb.hpp index 7d893c5a1a..78fe047169 100755 --- a/src/core/gb.hpp +++ b/src/core/gb.hpp @@ -27,9 +27,9 @@ * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef GAY_BERNE diff --git a/src/core/ghmc.cpp b/src/core/ghmc.cpp index 1933820df0..9754424976 100755 --- a/src/core/ghmc.cpp +++ b/src/core/ghmc.cpp @@ -33,11 +33,11 @@ #include "communication.hpp" #include "energy.hpp" #include "ghmc.hpp" +#include "global.hpp" #include "particle_data.hpp" #include "random.hpp" #include "statistics.hpp" #include "virtual_sites.hpp" -#include "global.hpp" /************************************************************/ @@ -168,7 +168,8 @@ void calc_kinetic(double *ek_trans, double *ek_rot) { #endif /* kinetic energy */ - et += (Utils::sqr(p.m.v[0]) + Utils::sqr(p.m.v[1]) + Utils::sqr(p.m.v[2])) * (p).p.mass; + et += (Utils::sqr(p.m.v[0]) + Utils::sqr(p.m.v[1]) + Utils::sqr(p.m.v[2])) * + (p).p.mass; /* rotational energy */ #ifdef ROTATION @@ -295,7 +296,7 @@ void partial_momentum_update() { for (int j = 0; j < 3; j++) { if (sigmat > 0.0) { p.m.v[j] = - cosp * (p.m.v[j]) + sinp * (sigmat * gaussian_random() * time_step); + cosp * (p.m.v[j]) + sinp * (sigmat * gaussian_random() * time_step); } else { p.m.v[j] = cosp * p.m.v[j]; } @@ -305,7 +306,7 @@ void partial_momentum_update() { #endif if (sigmar > 0.0) { p.m.omega[j] = - cosp * (p.m.omega[j]) + sinp * (sigmar * gaussian_random()); + cosp * (p.m.omega[j]) + sinp * (sigmar * gaussian_random()); } else { p.m.omega[j] = cosp * p.m.omega[j]; } diff --git a/src/core/ghosts.cpp b/src/core/ghosts.cpp index 3940dce773..669e6d0f64 100755 --- a/src/core/ghosts.cpp +++ b/src/core/ghosts.cpp @@ -1,35 +1,35 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file ghosts.cpp Ghost particles and particle exchange. * * For more information on ghosts, - * see \ref ghosts.hpp "ghosts.hpp" + * see \ref ghosts.hpp "ghosts.hpp" */ #include "ghosts.hpp" #include "cells.hpp" #include "communication.hpp" -#include "particle_data.hpp" -#include "utils.hpp" #include "debug.hpp" #include "errorhandling.hpp" +#include "particle_data.hpp" +#include "utils.hpp" #include #include @@ -55,42 +55,45 @@ static char *r_buffer = nullptr; std::vector r_bondbuffer; -/** whether the ghosts should also have velocity information, e. g. for DPD or RATTLE. +/** whether the ghosts should also have velocity information, e. g. for DPD or + RATTLE. You need this whenever you need the relative velocity of two particles. NO CHANGES OF THIS VALUE OUTSIDE OF \ref on_ghost_flags_change !!!! */ int ghosts_have_v = 0; -void prepare_comm(GhostCommunicator *comm, int data_parts, int num) -{ +void prepare_comm(GhostCommunicator *comm, int data_parts, int num) { assert(comm); comm->data_parts = data_parts; - GHOST_TRACE(fprintf(stderr, "%d: prepare_comm, data_parts = %d\n", this_node, comm->data_parts)); + GHOST_TRACE(fprintf(stderr, "%d: prepare_comm, data_parts = %d\n", this_node, + comm->data_parts)); comm->num = num; - comm->comm = (GhostCommunication*)Utils::malloc(num*sizeof(GhostCommunication)); - for(int i=0; icomm[i].shift[0]=comm->comm[i].shift[1]=comm->comm[i].shift[2]=0.0; + comm->comm = + (GhostCommunication *)Utils::malloc(num * sizeof(GhostCommunication)); + for (int i = 0; i < num; i++) { + comm->comm[i].shift[0] = comm->comm[i].shift[1] = comm->comm[i].shift[2] = + 0.0; comm->comm[i].n_part_lists = 0; comm->comm[i].part_lists = nullptr; } } -void free_comm(GhostCommunicator *comm) -{ +void free_comm(GhostCommunicator *comm) { int n; - GHOST_TRACE(fprintf(stderr,"%d: free_comm: %p has %d ghost communications\n",this_node,(void*) comm,comm->num)); - for (n = 0; n < comm->num; n++) free(comm->comm[n].part_lists); + GHOST_TRACE(fprintf(stderr, "%d: free_comm: %p has %d ghost communications\n", + this_node, (void *)comm, comm->num)); + for (n = 0; n < comm->num; n++) + free(comm->comm[n].part_lists); free(comm->comm); } -int calc_transmit_size(GhostCommunication *gc, int data_parts) -{ +int calc_transmit_size(GhostCommunication *gc, int data_parts) { int n_buffer_new; if (data_parts & GHOSTTRANS_PARTNUM) - n_buffer_new = sizeof(int)*gc->n_part_lists; + n_buffer_new = sizeof(int) * gc->n_part_lists; else { int count = 0; for (int p = 0; p < gc->n_part_lists; p++) @@ -99,7 +102,7 @@ int calc_transmit_size(GhostCommunication *gc, int data_parts) n_buffer_new = 0; if (data_parts & GHOSTTRANS_PROPRTS) { n_buffer_new += sizeof(ParticleProperties); - // sending size of bond/exclusion lists +// sending size of bond/exclusion lists #ifdef GHOSTS_HAVE_BONDS n_buffer_new += sizeof(int); #ifdef EXCLUSIONS @@ -226,35 +229,34 @@ void prepare_send_buffer(GhostCommunication *gc, int data_parts) { } } -static void prepare_ghost_cell(Cell *cell, int size) -{ +static void prepare_ghost_cell(Cell *cell, int size) { #ifdef GHOSTS_HAVE_BONDS // free all allocated information, will be resent { - int np = cell->n; + int np = cell->n; Particle *part = cell->part; for (int p = 0; p < np; p++) { free_particle(part + p); } - } + } #endif cell->resize(size); // invalidate pointers etc { - int np = cell->n; + int np = cell->n; Particle *part = cell->part; for (int p = 0; p < np; p++) { - Particle *pt = new(&part[p]) Particle(); + Particle *pt = new (&part[p]) Particle(); - //init ghost variable - pt->l.ghost=1; + // init ghost variable + pt->l.ghost = 1; } } } -void prepare_recv_buffer(GhostCommunication *gc, int data_parts) -{ - GHOST_TRACE(fprintf(stderr, "%d: prepare receiving from %d\n", this_node, gc->node)); +void prepare_recv_buffer(GhostCommunication *gc, int data_parts) { + GHOST_TRACE( + fprintf(stderr, "%d: prepare receiving from %d\n", this_node, gc->node)); /* reallocate recv buffer */ n_r_buffer = calc_transmit_size(gc, data_parts); if (n_r_buffer > max_r_buffer) { @@ -264,8 +266,7 @@ void prepare_recv_buffer(GhostCommunication *gc, int data_parts) GHOST_TRACE(fprintf(stderr, "%d: will get %d\n", this_node, n_r_buffer)); } -void put_recv_buffer(GhostCommunication *gc, int data_parts) -{ +void put_recv_buffer(GhostCommunication *gc, int data_parts) { /* put back data */ char *retrieve = r_buffer; @@ -274,65 +275,65 @@ void put_recv_buffer(GhostCommunication *gc, int data_parts) for (int pl = 0; pl < gc->n_part_lists; pl++) { auto cur_list = gc->part_lists[pl]; if (data_parts & GHOSTTRANS_PARTNUM) { - GHOST_TRACE(fprintf(stderr, "%d: reallocating cell %p to size %d, assigned to node %d\n", - this_node, (void*) cur_list, *(int *)retrieve, gc->node)); + GHOST_TRACE(fprintf( + stderr, "%d: reallocating cell %p to size %d, assigned to node %d\n", + this_node, (void *)cur_list, *(int *)retrieve, gc->node)); prepare_ghost_cell(cur_list, *(int *)retrieve); retrieve += sizeof(int); - } - else { - int np = cur_list->n; + } else { + int np = cur_list->n; Particle *part = cur_list->part; for (int p = 0; p < np; p++) { - Particle *pt = &part[p]; - if (data_parts & GHOSTTRANS_PROPRTS) { - memmove(&pt->p, retrieve, sizeof(ParticleProperties)); - retrieve += sizeof(ParticleProperties); + Particle *pt = &part[p]; + if (data_parts & GHOSTTRANS_PROPRTS) { + memmove(&pt->p, retrieve, sizeof(ParticleProperties)); + retrieve += sizeof(ParticleProperties); #ifdef GHOSTS_HAVE_BONDS int n_bonds; - memmove(&n_bonds, retrieve, sizeof(int)); - retrieve += sizeof(int); + memmove(&n_bonds, retrieve, sizeof(int)); + retrieve += sizeof(int); if (n_bonds) { - pt->bl.resize(n_bonds); + pt->bl.resize(n_bonds); std::copy_n(bond_retrieve, n_bonds, pt->bl.begin()); bond_retrieve += n_bonds; } #ifdef EXCLUSIONS int n_exclusions; - memmove(&n_exclusions, retrieve, sizeof(int)); - retrieve += sizeof(int); + memmove(&n_exclusions, retrieve, sizeof(int)); + retrieve += sizeof(int); if (n_exclusions) { - pt->el.resize(n_exclusions); + pt->el.resize(n_exclusions); std::copy_n(bond_retrieve, n_exclusions, pt->el.begin()); bond_retrieve += n_exclusions; } #endif #endif - if (local_particles[pt->p.identity] == nullptr) { - local_particles[pt->p.identity] = pt; - } - } - if (data_parts & GHOSTTRANS_POSITION) { - memmove(&pt->r, retrieve, sizeof(ParticlePosition)); - retrieve += sizeof(ParticlePosition); - } - if (data_parts & GHOSTTRANS_MOMENTUM) { - memmove(&pt->m, retrieve, sizeof(ParticleMomentum)); - retrieve += sizeof(ParticleMomentum); - } - if (data_parts & GHOSTTRANS_FORCE) { - memmove(&pt->f, retrieve, sizeof(ParticleForce)); - retrieve += sizeof(ParticleForce); - } + if (local_particles[pt->p.identity] == nullptr) { + local_particles[pt->p.identity] = pt; + } + } + if (data_parts & GHOSTTRANS_POSITION) { + memmove(&pt->r, retrieve, sizeof(ParticlePosition)); + retrieve += sizeof(ParticlePosition); + } + if (data_parts & GHOSTTRANS_MOMENTUM) { + memmove(&pt->m, retrieve, sizeof(ParticleMomentum)); + retrieve += sizeof(ParticleMomentum); + } + if (data_parts & GHOSTTRANS_FORCE) { + memmove(&pt->f, retrieve, sizeof(ParticleForce)); + retrieve += sizeof(ParticleForce); + } #ifdef LB - if (data_parts & GHOSTTRANS_COUPLING) { - memmove(&pt->lc, retrieve, sizeof(ParticleLatticeCoupling)); - retrieve += sizeof(ParticleLatticeCoupling); - } + if (data_parts & GHOSTTRANS_COUPLING) { + memmove(&pt->lc, retrieve, sizeof(ParticleLatticeCoupling)); + retrieve += sizeof(ParticleLatticeCoupling); + } #endif #ifdef ENGINE - if (data_parts & GHOSTTRANS_SWIMMING) { + if (data_parts & GHOSTTRANS_SWIMMING) { memmove(&pt->swim, retrieve, sizeof(ParticleParametersSwimming)); - retrieve += sizeof(ParticleParametersSwimming); + retrieve += sizeof(ParticleParametersSwimming); } #endif } @@ -346,20 +347,20 @@ void put_recv_buffer(GhostCommunication *gc, int data_parts) if (retrieve - r_buffer != n_r_buffer) { fprintf(stderr, "%d: recv buffer size %d differs " - "from what I read out (%ld)\n", + "from what I read out (%ld)\n", this_node, n_r_buffer, retrieve - r_buffer); errexit(); } if (bond_retrieve != r_bondbuffer.end()) { - fprintf(stderr, "%d: recv bond buffer was not used up, %ld elements remain\n", - this_node, r_bondbuffer.end() - bond_retrieve ); + fprintf(stderr, + "%d: recv bond buffer was not used up, %ld elements remain\n", + this_node, r_bondbuffer.end() - bond_retrieve); errexit(); } r_bondbuffer.resize(0); } -void add_forces_from_recv_buffer(GhostCommunication *gc) -{ +void add_forces_from_recv_buffer(GhostCommunication *gc) { int pl, p; Particle *part, *pt; char *retrieve; @@ -372,84 +373,80 @@ void add_forces_from_recv_buffer(GhostCommunication *gc) for (p = 0; p < np; p++) { pt = &part[p]; pt->f += *(reinterpret_cast(retrieve)); - retrieve += sizeof(ParticleForce); + retrieve += sizeof(ParticleForce); } } if (retrieve - r_buffer != n_r_buffer) { fprintf(stderr, "%d: recv buffer size %d differs " - "from what I put in %ld\n", + "from what I put in %ld\n", this_node, n_r_buffer, retrieve - r_buffer); errexit(); } } -void cell_cell_transfer(GhostCommunication *gc, int data_parts) -{ +void cell_cell_transfer(GhostCommunication *gc, int data_parts) { int pl, p, offset; Particle *part1, *part2, *pt1, *pt2; - GHOST_TRACE(fprintf(stderr, "%d: local_transfer: type %d data_parts %d\n", this_node,gc->type,data_parts)); + GHOST_TRACE(fprintf(stderr, "%d: local_transfer: type %d data_parts %d\n", + this_node, gc->type, data_parts)); /* transfer data */ - offset = gc->n_part_lists/2; + offset = gc->n_part_lists / 2; for (pl = 0; pl < offset; pl++) { Cell *src_list = gc->part_lists[pl]; Cell *dst_list = gc->part_lists[pl + offset]; if (data_parts & GHOSTTRANS_PARTNUM) { - prepare_ghost_cell(dst_list, src_list->n); - } - else { + prepare_ghost_cell(dst_list, src_list->n); + } else { int np = src_list->n; part1 = src_list->part; part2 = dst_list->part; for (p = 0; p < np; p++) { - pt1 = &part1[p]; - pt2 = &part2[p]; - if (data_parts & GHOSTTRANS_PROPRTS) { - memmove(&pt2->p, &pt1->p, sizeof(ParticleProperties)); + pt1 = &part1[p]; + pt2 = &part2[p]; + if (data_parts & GHOSTTRANS_PROPRTS) { + memmove(&pt2->p, &pt1->p, sizeof(ParticleProperties)); #ifdef GHOSTS_HAVE_BONDS - pt2->bl = pt1->bl; + pt2->bl = pt1->bl; #ifdef EXCLUSIONS - pt2->el = pt1->el; + pt2->el = pt1->el; #endif #endif } - if (data_parts & GHOSTTRANS_POSSHFTD) { - /* ok, this is not nice, but perhaps fast */ - int i; - memmove(&pt2->r, &pt1->r, sizeof(ParticlePosition)); - for (i = 0; i < 3; i++) - pt2->r.p[i] += gc->shift[i]; - } - else if (data_parts & GHOSTTRANS_POSITION) - memmove(&pt2->r, &pt1->r, sizeof(ParticlePosition)); - if (data_parts & GHOSTTRANS_MOMENTUM) { - memmove(&pt2->m, &pt1->m, sizeof(ParticleMomentum)); - } - if (data_parts & GHOSTTRANS_FORCE) - pt2->f += pt1->f; + if (data_parts & GHOSTTRANS_POSSHFTD) { + /* ok, this is not nice, but perhaps fast */ + int i; + memmove(&pt2->r, &pt1->r, sizeof(ParticlePosition)); + for (i = 0; i < 3; i++) + pt2->r.p[i] += gc->shift[i]; + } else if (data_parts & GHOSTTRANS_POSITION) + memmove(&pt2->r, &pt1->r, sizeof(ParticlePosition)); + if (data_parts & GHOSTTRANS_MOMENTUM) { + memmove(&pt2->m, &pt1->m, sizeof(ParticleMomentum)); + } + if (data_parts & GHOSTTRANS_FORCE) + pt2->f += pt1->f; #ifdef LB - if (data_parts & GHOSTTRANS_COUPLING) - memmove(&pt2->lc, &pt1->lc, sizeof(ParticleLatticeCoupling)); + if (data_parts & GHOSTTRANS_COUPLING) + memmove(&pt2->lc, &pt1->lc, sizeof(ParticleLatticeCoupling)); #endif #ifdef ENGINE - if (data_parts & GHOSTTRANS_SWIMMING) - memmove(&pt2->swim, &pt1->swim, sizeof(ParticleParametersSwimming)); + if (data_parts & GHOSTTRANS_SWIMMING) + memmove(&pt2->swim, &pt1->swim, sizeof(ParticleParametersSwimming)); #endif } } } } -void reduce_forces_sum(void *add, void *to, int *len, MPI_Datatype *type) -{ - ParticleForce - *cadd = static_cast(add), - *cto = static_cast(to); - int i, clen = *len/sizeof(ParticleForce); - +void reduce_forces_sum(void *add, void *to, int *len, MPI_Datatype *type) { + ParticleForce *cadd = static_cast(add), + *cto = static_cast(to); + int i, clen = *len / sizeof(ParticleForce); + if (*type != MPI_BYTE || (*len % sizeof(ParticleForce)) != 0) { fprintf(stderr, "%d: transfer data type wrong\n", this_node); errexit(); @@ -459,21 +456,18 @@ void reduce_forces_sum(void *add, void *to, int *len, MPI_Datatype *type) cto[i] += cadd[i]; } -static int is_send_op(int comm_type, int node) -{ +static int is_send_op(int comm_type, int node) { return ((comm_type == GHOST_SEND) || (comm_type == GHOST_RDCE) || (comm_type == GHOST_BCST && node == this_node)); } -static int is_recv_op(int comm_type, int node) -{ +static int is_recv_op(int comm_type, int node) { return ((comm_type == GHOST_RECV) || (comm_type == GHOST_BCST && node != this_node) || (comm_type == GHOST_RDCE && node == this_node)); } -void ghost_communicator(GhostCommunicator *gc) -{ +void ghost_communicator(GhostCommunicator *gc) { MPI_Status status; int n, n2; int data_parts = gc->data_parts; @@ -482,103 +476,125 @@ void ghost_communicator(GhostCommunicator *gc) if (ghosts_have_v && (data_parts & GHOSTTRANS_POSITION)) data_parts |= GHOSTTRANS_MOMENTUM; - - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm %p, data_parts %d\n", this_node, (void*) gc, data_parts)); + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm %p, data_parts %d\n", this_node, + (void *)gc, data_parts)); for (n = 0; n < gc->num; n++) { GhostCommunication *gcn = &gc->comm[n]; int comm_type = gcn->type & GHOST_JOBMASK; - int prefetch = gcn->type & GHOST_PREFETCH; + int prefetch = gcn->type & GHOST_PREFETCH; int poststore = gcn->type & GHOST_PSTSTORE; - int node = gcn->node; - - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm round %d, job %x\n", this_node, n, gc->comm[n].type)); - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm shift %f %f %f\n",this_node, gc->comm[n].shift[0], gc->comm[n].shift[1], gc->comm[n].shift[2])); + int node = gcn->node; + + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm round %d, job %x\n", this_node, + n, gc->comm[n].type)); + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm shift %f %f %f\n", this_node, + gc->comm[n].shift[0], gc->comm[n].shift[1], + gc->comm[n].shift[2])); if (comm_type == GHOST_LOCL) cell_cell_transfer(gcn, data_parts); else { /* prepare send buffer if necessary */ if (is_send_op(comm_type, node)) { - /* ok, we send this step, prepare send buffer if not yet done */ - if (!prefetch) - prepare_send_buffer(gcn, data_parts); - else { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm using prefetched data for operation %d, sending to %d\n", this_node, n, node)); + /* ok, we send this step, prepare send buffer if not yet done */ + if (!prefetch) + prepare_send_buffer(gcn, data_parts); + else { + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm using prefetched data " + "for operation %d, sending to %d\n", + this_node, n, node)); #ifdef ADDITIONAL_CHECKS - if (n_s_buffer != calc_transmit_size(gcn, data_parts)) { - fprintf(stderr, "%d: ghost_comm transmission size and current size of cells to transmit do not match\n", this_node); - errexit(); - } + if (n_s_buffer != calc_transmit_size(gcn, data_parts)) { + fprintf(stderr, "%d: ghost_comm transmission size and current size " + "of cells to transmit do not match\n", + this_node); + errexit(); + } #endif - } - } - else { - /* we do not send this time, let's look for a prefetch */ - if (prefetch) { - /* find next action where we send and which has PREFETCH set */ - for (n2 = n+1; n2 < gc->num; n2++) { - GhostCommunication *gcn2 = &gc->comm[n2]; - int comm_type2 = gcn2->type & GHOST_JOBMASK; - int prefetch2 = gcn2->type & GHOST_PREFETCH; - int node2 = gcn2->node; - if (is_send_op(comm_type2, node2) && prefetch2) { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm prefetch operation %d, is send/bcast to/from %d\n", this_node, n2, node2)); - prepare_send_buffer(gcn2, data_parts); - break; - } - } - } + } + } else { + /* we do not send this time, let's look for a prefetch */ + if (prefetch) { + /* find next action where we send and which has PREFETCH set */ + for (n2 = n + 1; n2 < gc->num; n2++) { + GhostCommunication *gcn2 = &gc->comm[n2]; + int comm_type2 = gcn2->type & GHOST_JOBMASK; + int prefetch2 = gcn2->type & GHOST_PREFETCH; + int node2 = gcn2->node; + if (is_send_op(comm_type2, node2) && prefetch2) { + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm prefetch operation " + "%d, is send/bcast to/from %d\n", + this_node, n2, node2)); + prepare_send_buffer(gcn2, data_parts); + break; + } + } + } } /* recv buffer for recv and multinode operations to this node */ if (is_recv_op(comm_type, node)) - prepare_recv_buffer(gcn, data_parts); + prepare_recv_buffer(gcn, data_parts); /* transfer data */ switch (comm_type) { case GHOST_RECV: { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm receive from %d (%d bytes)\n", this_node, node, n_r_buffer)); - MPI_Recv(r_buffer, n_r_buffer, MPI_BYTE, node, REQ_GHOST_SEND, comm_cart, &status); + GHOST_TRACE(fprintf(stderr, + "%d: ghost_comm receive from %d (%d bytes)\n", + this_node, node, n_r_buffer)); + MPI_Recv(r_buffer, n_r_buffer, MPI_BYTE, node, REQ_GHOST_SEND, + comm_cart, &status); if (data_parts & GHOSTTRANS_PROPRTS) { int n_bonds = *(int *)(r_buffer + n_r_buffer - sizeof(int)); - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm receive from %d (%d bonds)\n", this_node, node, n_bonds)); + GHOST_TRACE(fprintf(stderr, + "%d: ghost_comm receive from %d (%d bonds)\n", + this_node, node, n_bonds)); if (n_bonds) { r_bondbuffer.resize(n_bonds); - MPI_Recv(&r_bondbuffer[0], n_bonds, MPI_INT, node, REQ_GHOST_SEND, comm_cart, &status); + MPI_Recv(&r_bondbuffer[0], n_bonds, MPI_INT, node, REQ_GHOST_SEND, + comm_cart, &status); } } - break; + break; } case GHOST_SEND: { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm send to %d (%d bytes)\n", this_node, node, n_s_buffer)); - MPI_Send(s_buffer, n_s_buffer, MPI_BYTE, node, REQ_GHOST_SEND, comm_cart); + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm send to %d (%d bytes)\n", + this_node, node, n_s_buffer)); + MPI_Send(s_buffer, n_s_buffer, MPI_BYTE, node, REQ_GHOST_SEND, + comm_cart); int n_bonds = s_bondbuffer.size(); if (!(data_parts & GHOSTTRANS_PROPRTS) && n_bonds > 0) { - fprintf(stderr, "%d: INTERNAL ERROR: not sending properties, but bond buffer not empty\n", this_node); + fprintf(stderr, "%d: INTERNAL ERROR: not sending properties, but " + "bond buffer not empty\n", + this_node); errexit(); } - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm send to %d (%d ints)\n", this_node, node, n_bonds)); + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm send to %d (%d ints)\n", + this_node, node, n_bonds)); if (n_bonds) { - MPI_Send(&s_bondbuffer[0], n_bonds, MPI_INT, node, REQ_GHOST_SEND, comm_cart); + MPI_Send(&s_bondbuffer[0], n_bonds, MPI_INT, node, REQ_GHOST_SEND, + comm_cart); } break; } case GHOST_BCST: - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm bcast from %d (%d bytes)\n", this_node, node, - (node == this_node) ? n_s_buffer : n_r_buffer)); - if (node == this_node) { - MPI_Bcast(s_buffer, n_s_buffer, MPI_BYTE, node, comm_cart); + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm bcast from %d (%d bytes)\n", + this_node, node, + (node == this_node) ? n_s_buffer : n_r_buffer)); + if (node == this_node) { + MPI_Bcast(s_buffer, n_s_buffer, MPI_BYTE, node, comm_cart); int n_bonds = s_bondbuffer.size(); if (!(data_parts & GHOSTTRANS_PROPRTS) && n_bonds > 0) { - fprintf(stderr, "%d: INTERNAL ERROR: not sending properties, but bond buffer not empty\n", this_node); + fprintf(stderr, "%d: INTERNAL ERROR: not sending properties, but " + "bond buffer not empty\n", + this_node); errexit(); } if (n_bonds) { MPI_Bcast(&s_bondbuffer[0], n_bonds, MPI_INT, node, comm_cart); } - } - else { - MPI_Bcast(r_buffer, n_r_buffer, MPI_BYTE, node, comm_cart); + } else { + MPI_Bcast(r_buffer, n_r_buffer, MPI_BYTE, node, comm_cart); if (data_parts & GHOSTTRANS_PROPRTS) { int n_bonds = *(int *)(r_buffer + n_r_buffer - sizeof(int)); if (n_bonds) { @@ -587,7 +603,7 @@ void ghost_communicator(GhostCommunicator *gc) } } } - break; + break; case GHOST_RDCE: { GHOST_TRACE(fprintf(stderr, "%d: ghost_comm reduce to %d (%d bytes)\n", this_node, node, n_s_buffer)); @@ -605,46 +621,53 @@ void ghost_communicator(GhostCommunicator *gc) } GHOST_TRACE(fprintf(stderr, "%d: ghost_comm done\n", this_node)); - /* recv op; write back data directly, if no PSTSTORE delay is requested. */ + /* recv op; write back data directly, if no PSTSTORE delay is requested. + */ if (is_recv_op(comm_type, node)) { - if (!poststore) { - /* forces have to be added, the rest overwritten. Exception is RDCE, where the addition - is integrated into the communication. */ - if (data_parts == GHOSTTRANS_FORCE && comm_type != GHOST_RDCE) - add_forces_from_recv_buffer(gcn); - else - put_recv_buffer(gcn, data_parts); - } - else { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm delaying operation %d, recv from %d\n", this_node, n, node)); - } - } - else { - /* send op; write back delayed data from last recv, when this was a prefetch send. */ - if (poststore) { - /* find previous action where we recv and which has PSTSTORE set */ - for (n2 = n-1; n2 >= 0; n2--) { - GhostCommunication *gcn2 = &gc->comm[n2]; - int comm_type2 = gcn2->type & GHOST_JOBMASK; - int poststore2 = gcn2->type & GHOST_PSTSTORE; - int node2 = gcn2->node; - if (is_recv_op(comm_type2, node2) && poststore2) { - GHOST_TRACE(fprintf(stderr, "%d: ghost_comm storing delayed recv, operation %d, from %d\n", this_node, n2, node2)); + if (!poststore) { + /* forces have to be added, the rest overwritten. Exception is RDCE, + where the addition + is integrated into the communication. */ + if (data_parts == GHOSTTRANS_FORCE && comm_type != GHOST_RDCE) + add_forces_from_recv_buffer(gcn); + else + put_recv_buffer(gcn, data_parts); + } else { + GHOST_TRACE(fprintf( + stderr, "%d: ghost_comm delaying operation %d, recv from %d\n", + this_node, n, node)); + } + } else { + /* send op; write back delayed data from last recv, when this was a + * prefetch send. */ + if (poststore) { + /* find previous action where we recv and which has PSTSTORE set */ + for (n2 = n - 1; n2 >= 0; n2--) { + GhostCommunication *gcn2 = &gc->comm[n2]; + int comm_type2 = gcn2->type & GHOST_JOBMASK; + int poststore2 = gcn2->type & GHOST_PSTSTORE; + int node2 = gcn2->node; + if (is_recv_op(comm_type2, node2) && poststore2) { + GHOST_TRACE(fprintf(stderr, "%d: ghost_comm storing delayed " + "recv, operation %d, from %d\n", + this_node, n2, node2)); #ifdef ADDITIONAL_CHECKS - if (n_r_buffer != calc_transmit_size(gcn2, data_parts)) { - fprintf(stderr, "%d: ghost_comm transmission size and current size of cells to transmit do not match\n", this_node); - errexit(); - } + if (n_r_buffer != calc_transmit_size(gcn2, data_parts)) { + fprintf(stderr, "%d: ghost_comm transmission size and current " + "size of cells to transmit do not match\n", + this_node); + errexit(); + } #endif - /* as above */ - if (data_parts == GHOSTTRANS_FORCE && comm_type != GHOST_RDCE) - add_forces_from_recv_buffer(gcn2); - else - put_recv_buffer(gcn2, data_parts); - break; - } - } - } + /* as above */ + if (data_parts == GHOSTTRANS_FORCE && comm_type != GHOST_RDCE) + add_forces_from_recv_buffer(gcn2); + else + put_recv_buffer(gcn2, data_parts); + break; + } + } + } } } } @@ -652,20 +675,19 @@ void ghost_communicator(GhostCommunicator *gc) /** Go through \ref ghost_cells and remove the ghost entries from \ref local_particles. Part of \ref dd_exchange_and_sort_particles.*/ -void invalidate_ghosts() -{ +void invalidate_ghosts() { int c, p; /* remove ghosts, but keep Real Particles */ - for(c=0; cpart; int np = ghost_cells.cell[c]->n; - for(p=0 ; pn = 0; } diff --git a/src/core/ghosts.hpp b/src/core/ghosts.hpp index eca1829304..ccfee823b6 100755 --- a/src/core/ghosts.hpp +++ b/src/core/ghosts.hpp @@ -1,92 +1,121 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#ifndef _GHOSTS_H -#define _GHOSTS_H +#ifndef _GHOSTS_H +#define _GHOSTS_H /** \file ghosts.hpp Ghost particles and particle exchange. - + In this file you find everything concerning the exchange of particle data (particles, ghosts, positions and forces) for short range interactions between the spacial domains of neighbouring nodes.

How does this work

-The ghost communication transfers data from cells on one node to cells on another node during -the integration process. Note that data can only be transferred from one cell to one other, and -the contents of the other cell will be overwritten. This communication is invoked by the integrator, -at four different times in an integration step. These steps are reflected in \ref cell_structure structure, +The ghost communication transfers data from cells on one node to cells on +another node during +the integration process. Note that data can only be transferred from one cell to +one other, and +the contents of the other cell will be overwritten. This communication is +invoked by the integrator, +at four different times in an integration step. These steps are reflected in +\ref cell_structure structure, since they are treated differently by different cell systems:
    -
  • ghost_cells are used to transfer the cell sizes, i.e., make sure that for all later transfers +
  • ghost_cells are used to transfer the cell sizes, i.e., make sure that for +all later transfers the target cell has the same size as the source cell. -
  • exchange_ghosts sets up all information on the ghosts that is necessary. Normally transfers the +
  • exchange_ghosts sets up all information on the ghosts that is necessary. +Normally transfers the (shifted) position and particle properties. -
  • update_ghosts is used to update the particle properties if no particles have been moved between cells. - Therefore only the positions are transferred, otherwise this normally looks pretty much like the +
  • update_ghosts is used to update the particle properties if no particles +have been moved between cells. + Therefore only the positions are transferred, otherwise this normally +looks pretty much like the exchange_ghosts. -
  • collect_ghost_forces finally is used to transfer back forces that were exerted on a ghost particle. They - are simply added again to the force of the real particle. The communication process is therefore inverted - with respect to exchange_ghosts and update_ghosts, i.e., sending is replaced by receiving and the other way +
  • collect_ghost_forces finally is used to transfer back forces that were +exerted on a ghost particle. They + are simply added again to the force of the real particle. The +communication process is therefore inverted + with respect to exchange_ghosts and update_ghosts, i.e., sending is +replaced by receiving and the other way round.
-The particle data that has to be transferred, and especially from where to where, heavily depends on the cell system. -In Espresso, this is abstracted in form of ghost communicators (\ref GhostCommunicator) and ghost communications -(\ref GhostCommunication). The ghost communicators represent the four communications above and consist of the data to +The particle data that has to be transferred, and especially from where to +where, heavily depends on the cell system. +In Espresso, this is abstracted in form of ghost communicators (\ref +GhostCommunicator) and ghost communications +(\ref GhostCommunication). The ghost communicators represent the four +communications above and consist of the data to transfer (which is determined by their type) and a list of ghost communications. The data types are described by the particle data classes
  • GHOSTTRANS_PROPRTS transfers the \ref ParticleProperties
  • GHOSTTRANS_POSITION transfers the \ref ParticlePosition -
  • GHOSTTRANS_POSSHFTD is no transfer class, but marks that an additional vector, the shift, has to be - added to the positions. Can only be used together with GHOSTTRANS_POSITION. +
  • GHOSTTRANS_POSSHFTD is no transfer class, but marks that an additional +vector, the shift, has to be + added to the positions. Can only be used together with +GHOSTTRANS_POSITION.
  • GHOSTTRANS_MOMENTUM transfers the \ref ParticleMomentum
  • GHOSTTRANS_FORCE transfers the \ref ParticleForce
  • GHOSTTRANS_PARTNUM transfers the cell sizes
-Each ghost communication describes a single communication of the local with another node (or all other nodes). The data +Each ghost communication describes a single communication of the local with +another node (or all other nodes). The data transferred can be any number of cells, there are five communication types:
  • GHOST_SEND sends data to one other node -
  • GHOST_RECV recvs data from one other node. In the case of forces, they are added up, everything else is overwritten +
  • GHOST_RECV recvs data from one other node. In the case of forces, they are +added up, everything else is overwritten
  • GHOST_BCST sends data to all nodes -
  • GHOST_RDCE recvs data from all nodes. In the case of forces, they are added up, everything else is overwritten -
  • GHOST_LOCL transfer data from a local cell to another local cell. In this case, the first half of the cells are the sending cells, +
  • GHOST_RDCE recvs data from all nodes. In the case of forces, they are +added up, everything else is overwritten +
  • GHOST_LOCL transfer data from a local cell to another local cell. In this +case, the first half of the cells are the sending cells, the other half are the corresponding receivers.
-Note that for the first four communications you have to make sure that when one node sends to another, that the sender has GHOST_SEND and the -receiver GHOST_RECV. In the case of GHOST_BCST rsp. GHOST_RDCE, all nodes have to have the same communication type and the same master +Note that for the first four communications you have to make sure that when one +node sends to another, that the sender has GHOST_SEND and the +receiver GHOST_RECV. In the case of GHOST_BCST rsp. GHOST_RDCE, all nodes have +to have the same communication type and the same master sender/receiver (just like the MPI commands). -A special topic are GHOST_PREFETCH and GHOST_PSTSTORE. For example, if all nodes broadcast to the other, the naive implementation will be that -n_nodes times a GHOST_BCST is done with different master nodes. But this means that each time n_nodes-1 nodes wait for the master to construct -its send buffer. Therefore there is the prefetch flag which can be set on a pair of recv/send operations. If the ghost communication reaches a -recv operation with prefetch, the next send operation (which must have the prefetch set!!) is searched and the send buffer already created. -When sending, this precreated send buffer is used. In the scenario above, all nodes create the send buffers simultaneously in the first -communication step, thereby reducing the latency a little bit. The pststore is similar and postpones the write back of received data until a +A special topic are GHOST_PREFETCH and GHOST_PSTSTORE. For example, if all nodes +broadcast to the other, the naive implementation will be that +n_nodes times a GHOST_BCST is done with different master nodes. But this means +that each time n_nodes-1 nodes wait for the master to construct +its send buffer. Therefore there is the prefetch flag which can be set on a pair +of recv/send operations. If the ghost communication reaches a +recv operation with prefetch, the next send operation (which must have the +prefetch set!!) is searched and the send buffer already created. +When sending, this precreated send buffer is used. In the scenario above, all +nodes create the send buffers simultaneously in the first +communication step, thereby reducing the latency a little bit. The pststore is +similar and postpones the write back of received data until a send operation (with a precreated send buffer) is finished. -The ghost communicators are created in the init routines of the cell systems, therefore have a look at \ref dd_topology_init or +The ghost communicators are created in the init routines of the cell systems, +therefore have a look at \ref dd_topology_init or \ref nsq_topology_init for further details. */ -#include #include "Cell.hpp" +#include /** \name Transfer types, for \ref GhostCommunicator::type */ /************************************************************/ @@ -104,28 +133,28 @@ The ghost communicators are created in the init routines of the cell systems, th #define GHOST_LOCL 4 /// mask to the job area of the transfer type -#define GHOST_JOBMASK 15 +#define GHOST_JOBMASK 15 /// additional flag for prefetching #define GHOST_PREFETCH 16 /// additional flag for poststoring #define GHOST_PSTSTORE 32 /*@}*/ - /** \name Transfer data classes, for \ref GhostCommunication::type */ /************************************************************/ /*@{*/ /// transfer \ref ParticleProperties -#define GHOSTTRANS_PROPRTS 1 +#define GHOSTTRANS_PROPRTS 1 /// transfer \ref ParticlePosition #define GHOSTTRANS_POSITION 2 -/** flag for \ref GHOSTTRANS_POSITION, shift the positions by \ref GhostCommunication::shift. +/** flag for \ref GHOSTTRANS_POSITION, shift the positions by \ref + GhostCommunication::shift. Must be or'd together with \ref GHOSTTRANS_POSITION */ #define GHOSTTRANS_POSSHFTD 4 /// transfer \ref ParticleMomentum #define GHOSTTRANS_MOMENTUM 8 /// transfer \ref ParticleForce -#define GHOSTTRANS_FORCE 16 +#define GHOSTTRANS_FORCE 16 #ifdef LB /// transfer \ref ParticleLatticeCoupling @@ -133,7 +162,7 @@ The ghost communicators are created in the init routines of the cell systems, th #endif /// resize the receiver particle arrays to the size of the senders -#define GHOSTTRANS_PARTNUM 64 +#define GHOSTTRANS_PARTNUM 64 #ifdef ENGINE /// transfer \ref ParticleParametersSwimming @@ -151,7 +180,8 @@ typedef struct { int type; /** Node to communicate with (to use with all MPI operations). */ int node; - /** MPI communicator handle (to use with GHOST_BCST, GHOST_GATH, GHOST_RDCE). */ + /** MPI communicator handle (to use with GHOST_BCST, GHOST_GATH, GHOST_RDCE). + */ MPI_Comm mpi_comm; /** Number of particle lists to communicate. */ @@ -159,8 +189,10 @@ typedef struct { /** Pointer array to particle lists to communicate. */ Cell **part_lists; - /** if \ref GhostCommunicator::data_parts has \ref GHOSTTRANS_POSSHFTD, then this is the shift vector. - Normally this a integer multiple of the box length. The shift is done on the sender side */ + /** if \ref GhostCommunicator::data_parts has \ref GHOSTTRANS_POSSHFTD, then + this is the shift vector. + Normally this a integer multiple of the box length. The shift is done on + the sender side */ double shift[3]; } GhostCommunication; diff --git a/src/core/global.cpp b/src/core/global.cpp index 278c9b330d..6cff548576 100755 --- a/src/core/global.cpp +++ b/src/core/global.cpp @@ -30,14 +30,14 @@ #include "grid.hpp" #include "initialize.hpp" #include "interaction_data.hpp" -#include "lattice.hpp" +#include "lattice.hpp" #include "layered.hpp" #include "npt.hpp" +#include "object-in-fluid/oif_global_forces.hpp" #include "rattle.hpp" #include "thermalized_bond.hpp" #include "tuning.hpp" #include "utils/mpi/all_compare.hpp" -#include "object-in-fluid/oif_global_forces.hpp" #include @@ -69,155 +69,154 @@ typedef struct { const std::unordered_map fields{ {FIELD_BOXL, - {box_l, Datafield::Type::DOUBLE, 3, "box_l"}}, /* 0 from grid.cpp */ - {FIELD_CELLGRID, - {dd.cell_grid, Datafield::Type::INT, 3, - "cell_grid"}}, /* 1 from cells.cpp */ - {FIELD_CELLSIZE, - {dd.cell_size, Datafield::Type::DOUBLE, 3, - "cell_size"}}, /* 2 from cells.cpp */ + {box_l, Datafield::Type::DOUBLE, 3, "box_l"}}, /* 0 from grid.cpp */ + {FIELD_CELLGRID, + {dd.cell_grid, Datafield::Type::INT, 3, + "cell_grid"}}, /* 1 from cells.cpp */ + {FIELD_CELLSIZE, + {dd.cell_size, Datafield::Type::DOUBLE, 3, + "cell_size"}}, /* 2 from cells.cpp */ #ifndef PARTICLE_ANISOTROPY - {FIELD_LANGEVIN_GAMMA, - {&langevin_gamma, Datafield::Type::DOUBLE, 1, - "gamma"}}, /* 5 from thermostat.cpp */ + {FIELD_LANGEVIN_GAMMA, + {&langevin_gamma, Datafield::Type::DOUBLE, 1, + "gamma"}}, /* 5 from thermostat.cpp */ #else - {FIELD_LANGEVIN_GAMMA, - {langevin_gamma.data(), Datafield::Type::DOUBLE, 3, - "gamma"}}, /* 5 from thermostat.cpp */ + {FIELD_LANGEVIN_GAMMA, + {langevin_gamma.data(), Datafield::Type::DOUBLE, 3, + "gamma"}}, /* 5 from thermostat.cpp */ #endif // PARTICLE_ANISOTROPY - {FIELD_INTEG_SWITCH, - {&integ_switch, Datafield::Type::INT, 1, - "integ_switch"}}, /* 7 from integrate.cpp */ - {FIELD_LBOXL, - {local_box_l, Datafield::Type::DOUBLE, 3, - "local_box_l"}}, /* 8 from global.cpp */ - {FIELD_MCUT, - {&max_cut, Datafield::Type::DOUBLE, 1, - "max_cut"}}, /* 9 from interaction_data.cpp */ - {FIELD_MAXNUMCELLS, - {&max_num_cells, Datafield::Type::INT, 1, - "max_num_cells"}}, /* 10 from cells.cpp */ - {FIELD_MAXPART, - {&max_seen_particle, Datafield::Type::INT, 1, - "max_part"}}, /* 11 from particle_data.cpp */ - {FIELD_MAXRANGE, - {&max_range, Datafield::Type::DOUBLE, 1, - "max_range"}}, /* 12 from integrate.cpp */ - {FIELD_MAXSKIN, - {&max_skin, Datafield::Type::DOUBLE, 1, - "max_skin"}}, /* 13 from integrate.cpp */ - {FIELD_MINNUMCELLS, - {&min_num_cells, Datafield::Type::INT, 1, - "min_num_cells"}}, /* 14 from cells.cpp */ - {FIELD_NLAYERS, - {&n_layers, Datafield::Type::INT, 1, - "n_layers"}}, /* 15 from layered.cpp */ - {FIELD_NNODES, - {&n_nodes, Datafield::Type::INT, 1, - "n_nodes"}}, /* 16 from communication.cpp */ - {FIELD_NPART, - {&n_part, Datafield::Type::INT, 1, "n_part"}}, /* 17 from particle.cpp */ - {FIELD_NPARTTYPE, - {&max_seen_particle_type, Datafield::Type::INT, 1, "max_seen_particle_type" - }}, /* 18 from interaction_data.cpp */ - {FIELD_RIGIDBONDS, - {&n_rigidbonds, Datafield::Type::INT, 1, - "n_rigidbonds"}}, /* 19 from rattle.cpp */ - {FIELD_NODEGRID, - {node_grid, Datafield::Type::INT, 3, "node_grid"}}, /* 20 from grid.cpp */ - {FIELD_NPTISO_G0, - {&nptiso_gamma0, Datafield::Type::DOUBLE, 1, - "nptiso_gamma0"}}, /* 21 from thermostat.cpp */ - {FIELD_NPTISO_GV, - {&nptiso_gammav, Datafield::Type::DOUBLE, 1, - "nptiso_gammav"}}, /* 22 from thermostat.cpp */ - {FIELD_NPTISO_PEXT, - {&nptiso.p_ext, Datafield::Type::DOUBLE, 1, - "npt_p_ext"}}, /* 23 from pressure.cpp */ - {FIELD_NPTISO_PINST, - {&nptiso.p_inst, Datafield::Type::DOUBLE, 1, - "npt_p_inst"}}, /* 24 from pressure.cpp */ - {FIELD_NPTISO_PINSTAV, - {&nptiso.p_inst_av, Datafield::Type::DOUBLE, 1, - "npt_p_inst_av"}}, /* 25 from pressure.cpp */ - {FIELD_NPTISO_PDIFF, - {&nptiso.p_diff, Datafield::Type::DOUBLE, 1, - "npt_p_diff"}}, /* 26 from pressure.cpp */ - {FIELD_NPTISO_PISTON, - {&nptiso.piston, Datafield::Type::DOUBLE, 1, - "npt_piston"}}, /* 27 from pressure.cpp */ - {FIELD_PERIODIC, - {&periodic, Datafield::Type::BOOL, 3, - "periodicity"}}, /* 28 from grid.cpp */ - {FIELD_SKIN, - {&skin, Datafield::Type::DOUBLE, 1, "skin"}}, /* 29 from integrate.cpp */ - {FIELD_TEMPERATURE, - {&temperature, Datafield::Type::DOUBLE, 1, - "temperature"}}, /* 30 from thermostat.cpp */ - {FIELD_THERMO_SWITCH, - {&thermo_switch, Datafield::Type::INT, 1, - "thermo_switch"}}, /* 31 from thermostat.cpp */ - {FIELD_SIMTIME, - {&sim_time, Datafield::Type::DOUBLE, 1, - "time"}}, /* 32 from integrate.cpp */ - {FIELD_TIMESTEP, - {&time_step, Datafield::Type::DOUBLE, 1, - "time_step"}}, /* 33 from integrate.cpp */ - {FIELD_TIMINGSAMP, - {&timing_samples, Datafield::Type::INT, 1, - "timings"}}, /* 34 from tuning.cpp */ - {FIELD_MCUT_NONBONDED, - {&max_cut_nonbonded, Datafield::Type::DOUBLE, 1, - "max_cut_nonbonded"}}, /* 35 from interaction_data.cpp */ - {FIELD_VERLETREUSE, - {&verlet_reuse, Datafield::Type::DOUBLE, 1, - "verlet_reuse"}}, /* 36 from integrate.cpp */ - {FIELD_LATTICE_SWITCH, - {&lattice_switch, Datafield::Type::INT, 1, - "lattice_switch"}}, /* 37 from lattice.cpp */ - {FIELD_MCUT_BONDED, - {&max_cut_bonded, Datafield::Type::DOUBLE, 1, - "max_cut_bonded"}}, /* 42 from interaction_data.cpp */ - {FIELD_MIN_GLOBAL_CUT, - {&min_global_cut, Datafield::Type::DOUBLE, 1, - "min_global_cut"}}, /* 43 from interaction_data.cpp */ - {FIELD_GHMC_NMD, - {&ghmc_nmd, Datafield::Type::INT, 1, - "ghmc_nmd"}}, /* 44 from thermostat.cpp */ - {FIELD_GHMC_PHI, - {&ghmc_phi, Datafield::Type::DOUBLE, 1, - "ghmc_phi"}}, /* 45 from thermostat.cpp */ - {FIELD_GHMC_RES, - {&ghmc_mc_res, Datafield::Type::INT, 1, - "ghmc_mc_res"}}, /* 46 from ghmc.cpp */ - {FIELD_GHMC_FLIP, - {&ghmc_mflip, Datafield::Type::INT, 1, - "ghmc_mflip"}}, /* 47 from ghmc.cpp */ - {FIELD_GHMC_SCALE, - {&ghmc_tscale, Datafield::Type::INT, 1, - "ghmc_tscale"}}, /* 48 from ghmc.cpp */ - {FIELD_WARNINGS, - {&warnings, Datafield::Type::INT, 1, "warnings" - }}, /* 50 from global.cpp */ + {FIELD_INTEG_SWITCH, + {&integ_switch, Datafield::Type::INT, 1, + "integ_switch"}}, /* 7 from integrate.cpp */ + {FIELD_LBOXL, + {local_box_l, Datafield::Type::DOUBLE, 3, + "local_box_l"}}, /* 8 from global.cpp */ + {FIELD_MCUT, + {&max_cut, Datafield::Type::DOUBLE, 1, + "max_cut"}}, /* 9 from interaction_data.cpp */ + {FIELD_MAXNUMCELLS, + {&max_num_cells, Datafield::Type::INT, 1, + "max_num_cells"}}, /* 10 from cells.cpp */ + {FIELD_MAXPART, + {&max_seen_particle, Datafield::Type::INT, 1, + "max_part"}}, /* 11 from particle_data.cpp */ + {FIELD_MAXRANGE, + {&max_range, Datafield::Type::DOUBLE, 1, + "max_range"}}, /* 12 from integrate.cpp */ + {FIELD_MAXSKIN, + {&max_skin, Datafield::Type::DOUBLE, 1, + "max_skin"}}, /* 13 from integrate.cpp */ + {FIELD_MINNUMCELLS, + {&min_num_cells, Datafield::Type::INT, 1, + "min_num_cells"}}, /* 14 from cells.cpp */ + {FIELD_NLAYERS, + {&n_layers, Datafield::Type::INT, 1, + "n_layers"}}, /* 15 from layered.cpp */ + {FIELD_NNODES, + {&n_nodes, Datafield::Type::INT, 1, + "n_nodes"}}, /* 16 from communication.cpp */ + {FIELD_NPART, + {&n_part, Datafield::Type::INT, 1, "n_part"}}, /* 17 from particle.cpp */ + {FIELD_NPARTTYPE, + {&max_seen_particle_type, Datafield::Type::INT, 1, + "max_seen_particle_type"}}, /* 18 from interaction_data.cpp */ + {FIELD_RIGIDBONDS, + {&n_rigidbonds, Datafield::Type::INT, 1, + "n_rigidbonds"}}, /* 19 from rattle.cpp */ + {FIELD_NODEGRID, + {node_grid, Datafield::Type::INT, 3, "node_grid"}}, /* 20 from grid.cpp */ + {FIELD_NPTISO_G0, + {&nptiso_gamma0, Datafield::Type::DOUBLE, 1, + "nptiso_gamma0"}}, /* 21 from thermostat.cpp */ + {FIELD_NPTISO_GV, + {&nptiso_gammav, Datafield::Type::DOUBLE, 1, + "nptiso_gammav"}}, /* 22 from thermostat.cpp */ + {FIELD_NPTISO_PEXT, + {&nptiso.p_ext, Datafield::Type::DOUBLE, 1, + "npt_p_ext"}}, /* 23 from pressure.cpp */ + {FIELD_NPTISO_PINST, + {&nptiso.p_inst, Datafield::Type::DOUBLE, 1, + "npt_p_inst"}}, /* 24 from pressure.cpp */ + {FIELD_NPTISO_PINSTAV, + {&nptiso.p_inst_av, Datafield::Type::DOUBLE, 1, + "npt_p_inst_av"}}, /* 25 from pressure.cpp */ + {FIELD_NPTISO_PDIFF, + {&nptiso.p_diff, Datafield::Type::DOUBLE, 1, + "npt_p_diff"}}, /* 26 from pressure.cpp */ + {FIELD_NPTISO_PISTON, + {&nptiso.piston, Datafield::Type::DOUBLE, 1, + "npt_piston"}}, /* 27 from pressure.cpp */ + {FIELD_PERIODIC, + {&periodic, Datafield::Type::BOOL, 3, + "periodicity"}}, /* 28 from grid.cpp */ + {FIELD_SKIN, + {&skin, Datafield::Type::DOUBLE, 1, "skin"}}, /* 29 from integrate.cpp */ + {FIELD_TEMPERATURE, + {&temperature, Datafield::Type::DOUBLE, 1, + "temperature"}}, /* 30 from thermostat.cpp */ + {FIELD_THERMO_SWITCH, + {&thermo_switch, Datafield::Type::INT, 1, + "thermo_switch"}}, /* 31 from thermostat.cpp */ + {FIELD_SIMTIME, + {&sim_time, Datafield::Type::DOUBLE, 1, + "time"}}, /* 32 from integrate.cpp */ + {FIELD_TIMESTEP, + {&time_step, Datafield::Type::DOUBLE, 1, + "time_step"}}, /* 33 from integrate.cpp */ + {FIELD_TIMINGSAMP, + {&timing_samples, Datafield::Type::INT, 1, + "timings"}}, /* 34 from tuning.cpp */ + {FIELD_MCUT_NONBONDED, + {&max_cut_nonbonded, Datafield::Type::DOUBLE, 1, + "max_cut_nonbonded"}}, /* 35 from interaction_data.cpp */ + {FIELD_VERLETREUSE, + {&verlet_reuse, Datafield::Type::DOUBLE, 1, + "verlet_reuse"}}, /* 36 from integrate.cpp */ + {FIELD_LATTICE_SWITCH, + {&lattice_switch, Datafield::Type::INT, 1, + "lattice_switch"}}, /* 37 from lattice.cpp */ + {FIELD_MCUT_BONDED, + {&max_cut_bonded, Datafield::Type::DOUBLE, 1, + "max_cut_bonded"}}, /* 42 from interaction_data.cpp */ + {FIELD_MIN_GLOBAL_CUT, + {&min_global_cut, Datafield::Type::DOUBLE, 1, + "min_global_cut"}}, /* 43 from interaction_data.cpp */ + {FIELD_GHMC_NMD, + {&ghmc_nmd, Datafield::Type::INT, 1, + "ghmc_nmd"}}, /* 44 from thermostat.cpp */ + {FIELD_GHMC_PHI, + {&ghmc_phi, Datafield::Type::DOUBLE, 1, + "ghmc_phi"}}, /* 45 from thermostat.cpp */ + {FIELD_GHMC_RES, + {&ghmc_mc_res, Datafield::Type::INT, 1, + "ghmc_mc_res"}}, /* 46 from ghmc.cpp */ + {FIELD_GHMC_FLIP, + {&ghmc_mflip, Datafield::Type::INT, 1, + "ghmc_mflip"}}, /* 47 from ghmc.cpp */ + {FIELD_GHMC_SCALE, + {&ghmc_tscale, Datafield::Type::INT, 1, + "ghmc_tscale"}}, /* 48 from ghmc.cpp */ + {FIELD_WARNINGS, + {&warnings, Datafield::Type::INT, 1, "warnings"}}, /* 50 from global.cpp */ #ifndef PARTICLE_ANISOTROPY - {FIELD_LANGEVIN_GAMMA_ROTATION, - {&langevin_gamma_rotation, Datafield::Type::DOUBLE, 1, - "gamma_rot"}}, /* 55 from thermostat.cpp */ + {FIELD_LANGEVIN_GAMMA_ROTATION, + {&langevin_gamma_rotation, Datafield::Type::DOUBLE, 1, + "gamma_rot"}}, /* 55 from thermostat.cpp */ #else - {FIELD_LANGEVIN_GAMMA_ROTATION, - {langevin_gamma_rotation.data(), Datafield::Type::DOUBLE, 3, - "gamma_rot"}}, /* 55 from thermostat.cpp */ + {FIELD_LANGEVIN_GAMMA_ROTATION, + {langevin_gamma_rotation.data(), Datafield::Type::DOUBLE, 3, + "gamma_rot"}}, /* 55 from thermostat.cpp */ #endif #ifdef OIF_GLOBAL_FORCES - {FIELD_MAX_OIF_OBJECTS, - {&max_oif_objects, Datafield::Type::INT, 1, "max_oif_objects"}}, + {FIELD_MAX_OIF_OBJECTS, + {&max_oif_objects, Datafield::Type::INT, 1, "max_oif_objects"}}, #endif - {FIELD_THERMALIZEDBONDS, - {&n_thermalized_bonds, Datafield::Type::INT, 1, - "n_thermalized_bonds"}}, /* 56 from thermalized_bond.cpp */ - {FIELD_FORCE_CAP, {&force_cap, Datafield::Type::DOUBLE, 1, "force_cap"}}, - {FIELD_THERMO_VIRTUAL, - {&thermo_virtual, Datafield::Type::BOOL, 1, "thermo_virtual"}}}; + {FIELD_THERMALIZEDBONDS, + {&n_thermalized_bonds, Datafield::Type::INT, 1, + "n_thermalized_bonds"}}, /* 56 from thermalized_bond.cpp */ + {FIELD_FORCE_CAP, {&force_cap, Datafield::Type::DOUBLE, 1, "force_cap"}}, + {FIELD_THERMO_VIRTUAL, + {&thermo_virtual, Datafield::Type::BOOL, 1, "thermo_virtual"}}}; std::size_t hash_value(Datafield const &field) { using boost::hash_range; @@ -247,7 +246,8 @@ void common_bcast_parameter(int i) { comm_cart); break; case Datafield::Type::BOOL: - static_assert(sizeof(bool) == sizeof(char), "bool datatype does not have the expected size"); + static_assert(sizeof(bool) == sizeof(char), + "bool datatype does not have the expected size"); MPI_Bcast((char *)fields.at(i).data, 1, MPI_CHAR, 0, comm_cart); break; case Datafield::Type::DOUBLE: diff --git a/src/core/grid.cpp b/src/core/grid.cpp index 0ca9b7d97a..59e7a4fcd5 100755 --- a/src/core/grid.cpp +++ b/src/core/grid.cpp @@ -24,10 +24,10 @@ * see \ref grid.hpp "grid.h". */ -#include "debug.hpp" #include "grid.hpp" #include "cells.hpp" #include "communication.hpp" +#include "debug.hpp" #include "global.hpp" #include "interaction_data.hpp" #include "utils.hpp" @@ -157,7 +157,7 @@ void grid_changed_n_nodes() { GRID_TRACE(fprintf(stderr, "%d: grid_changed_n_nodes:\n", this_node)); mpi_reshape_communicator({{node_grid[0], node_grid[1], node_grid[2]}}, - {{ 1, 1, 1}}); + {{1, 1, 1}}); MPI_Cart_coords(comm_cart, this_node, 3, node_pos); diff --git a/src/core/grid.hpp b/src/core/grid.hpp index 37a72da366..9b18635f3e 100755 --- a/src/core/grid.hpp +++ b/src/core/grid.hpp @@ -45,8 +45,8 @@ */ #include "RuntimeErrorStream.hpp" #include "communication.hpp" -#include "utils.hpp" #include "errorhandling.hpp" +#include "utils.hpp" #include @@ -207,8 +207,7 @@ Vector3d get_mi_vector(T const &a, U const &b) { i. e. a previously folded position will be folded correctly. */ template -void fold_coordinate(T1& pos, T2& vel, T3& image_box, - int dir) { +void fold_coordinate(T1 &pos, T2 &vel, T3 &image_box, int dir) { if (PERIODIC(dir)) { int img_count = (int)floor(pos[dir] * box_l_i[dir]); image_box[dir] += img_count; @@ -224,7 +223,6 @@ void fold_coordinate(T1& pos, T2& vel, T3& image_box, pos[dir] = 0; return; } - } } @@ -238,7 +236,7 @@ void fold_coordinate(T1& pos, T2& vel, T3& image_box, i. e. a previously folded position will be folded correctly. */ template -void fold_coordinate(T1& pos, T2& image_box, int dir) { +void fold_coordinate(T1 &pos, T2 &image_box, int dir) { double v[3]; fold_coordinate(pos, v, image_box, dir); } @@ -252,7 +250,7 @@ void fold_coordinate(T1& pos, T2& image_box, int dir) { i. e. a previously folded position will be folded correctly. */ template -inline void fold_position(T1& pos, T2& vel, T3& image_box) { +inline void fold_position(T1 &pos, T2 &vel, T3 &image_box) { for (int i = 0; i < 3; i++) fold_coordinate(pos, vel, image_box, i); } @@ -264,8 +262,7 @@ inline void fold_position(T1& pos, T2& vel, T3& image_box) { Both pos and image_box are I/O, i. e. a previously folded position will be folded correctly. */ -template -void fold_position(T1& pos, T2& image_box) { +template void fold_position(T1 &pos, T2 &image_box) { for (int i = 0; i < 3; i++) fold_coordinate(pos, image_box, i); } @@ -294,7 +291,6 @@ inline Vector3d folded_position(const Particle *p) { return folded_position(*p); } - /** unfold coordinates to physical position. \param pos the position \param vel the velocity @@ -304,18 +300,16 @@ inline Vector3d folded_position(const Particle *p) { afterwards. */ template -void unfold_position(T1& pos, T2& vel, T3& image_box) { +void unfold_position(T1 &pos, T2 &vel, T3 &image_box) { int i; for (i = 0; i < 3; i++) { pos[i] = pos[i] + image_box[i] * box_l[i]; image_box[i] = 0; } - } -inline -Vector3d unfolded_position(Particle const * p) { +inline Vector3d unfolded_position(Particle const *p) { Vector3d pos{p->r.p}; for (int i = 0; i < 3; i++) { pos[i] += p->l.i[i] * box_l[i]; @@ -336,7 +330,7 @@ inline Vector3d unfolded_position(Particle const &p) { afterwards. */ template -void unfold_position(T1& pos, T2& image_box) { +void unfold_position(T1 &pos, T2 &image_box) { double v[3]; unfold_position(pos, v, image_box); } diff --git a/src/core/halo.cpp b/src/core/halo.cpp index ac718c3404..20fef7bcb4 100755 --- a/src/core/halo.cpp +++ b/src/core/halo.cpp @@ -1,26 +1,26 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file halo.cpp - * - * Halo scheme for parallelization of lattice algorithms. + * + * Halo scheme for parallelization of lattice algorithms. * Implementation of file \ref halo.hpp. * */ @@ -29,27 +29,29 @@ #ifdef LATTICE -#include "utils.hpp" #include "debug.hpp" #include "grid.hpp" -#include "lattice.hpp" #include "halo.hpp" +#include "lattice.hpp" +#include "utils.hpp" /** Primitive fieldtypes and their initializers */ -struct _Fieldtype fieldtype_double = { 0, nullptr, nullptr, sizeof(double), 0, 0, 0, 0, nullptr }; +struct _Fieldtype fieldtype_double = {0, nullptr, nullptr, sizeof(double), 0, + 0, 0, 0, nullptr}; -/** Creates a fieldtype describing the data layout +/** Creates a fieldtype describing the data layout * @param count number of subtypes (Input) * @param lengths array of lenghts of the subtytpes (Input) * @param disps array of displacements the subtypes (Input) * @param extent extent of the whole new fieldtype (Input) * @param newtype newly created fieldtype (Input/Output) */ -void halo_create_fieldtype(int count, int* lengths, int *disps, int extent, Fieldtype *newtype) { - Fieldtype ntype = *newtype = (Fieldtype) Utils::malloc(sizeof(*ntype)); +void halo_create_fieldtype(int count, int *lengths, int *disps, int extent, + Fieldtype *newtype) { + Fieldtype ntype = *newtype = (Fieldtype)Utils::malloc(sizeof(*ntype)); ntype->subtype = nullptr; - ntype->vflag = 0; + ntype->vflag = 0; ntype->vblocks = 1; ntype->vstride = 1; @@ -58,82 +60,80 @@ void halo_create_fieldtype(int count, int* lengths, int *disps, int extent, Fiel ntype->count = count; ntype->extent = extent; - if (count>0) { + if (count > 0) { - ntype->lengths = (int*) Utils::malloc(count*2*sizeof(int)); - ntype->disps = (int *)((char *)ntype->lengths + count*sizeof(int)); - - for (int i=0;idisps[i] = disps[i]; - ntype->lengths[i] = lengths[i]; - } + ntype->lengths = (int *)Utils::malloc(count * 2 * sizeof(int)); + ntype->disps = (int *)((char *)ntype->lengths + count * sizeof(int)); + for (int i = 0; i < count; i++) { + ntype->disps[i] = disps[i]; + ntype->lengths[i] = lengths[i]; + } } - } /** Creates a field vector layout - * @param vblocks number of vector blocks(Input) + * @param vblocks number of vector blocks(Input) * @param vstride size of strides in field vector (Input) * @param vskip displacements of strides in field vector (Input) * @param oldtype fieldtype the vector is composed of (Input) * @param newtype newly created fieldtype (Input/Output) */ -void halo_create_field_vector(int vblocks, int vstride, int vskip, Fieldtype oldtype, Fieldtype *newtype) { +void halo_create_field_vector(int vblocks, int vstride, int vskip, + Fieldtype oldtype, Fieldtype *newtype) { int i; - Fieldtype ntype = *newtype = (Fieldtype) Utils::malloc(sizeof(*ntype)); - + Fieldtype ntype = *newtype = (Fieldtype)Utils::malloc(sizeof(*ntype)); + ntype->subtype = oldtype; - ntype->vflag = 1; + ntype->vflag = 1; ntype->vblocks = vblocks; ntype->vstride = vstride; - ntype->vskip = vskip; + ntype->vskip = vskip; + + ntype->extent = oldtype->extent * ((vblocks - 1) * vskip + vstride); - ntype->extent = oldtype->extent * ((vblocks-1)*vskip + vstride); - int count = ntype->count = oldtype->count; - ntype->lengths = (int*) Utils::malloc(count*2*sizeof(int)); - ntype->disps = (int *)((char *)ntype->lengths + count*sizeof(int)); - - for (i=0;idisps[i] = oldtype->disps[i]; - ntype->lengths[i] = oldtype->lengths[i]; - } + ntype->lengths = (int *)Utils::malloc(count * 2 * sizeof(int)); + ntype->disps = (int *)((char *)ntype->lengths + count * sizeof(int)); + for (i = 0; i < count; i++) { + ntype->disps[i] = oldtype->disps[i]; + ntype->lengths[i] = oldtype->lengths[i]; + } } -void halo_create_field_hvector(int vblocks, int vstride, int vskip, Fieldtype oldtype, Fieldtype *newtype) { +void halo_create_field_hvector(int vblocks, int vstride, int vskip, + Fieldtype oldtype, Fieldtype *newtype) { int i; - Fieldtype ntype = *newtype = (Fieldtype) Utils::malloc(sizeof(*ntype)); + Fieldtype ntype = *newtype = (Fieldtype)Utils::malloc(sizeof(*ntype)); ntype->subtype = oldtype; - ntype->vflag = 0; + ntype->vflag = 0; ntype->vblocks = vblocks; ntype->vstride = vstride; - ntype->vskip = vskip; + ntype->vskip = vskip; - ntype->extent = oldtype->extent*vstride + (vblocks-1)*vskip; + ntype->extent = oldtype->extent * vstride + (vblocks - 1) * vskip; int count = ntype->count = oldtype->count; - ntype->lengths = (int*) Utils::malloc(count*2*sizeof(int)); - ntype->disps = (int *)((char *)ntype->lengths + count*sizeof(int)); - - for (i=0;idisps[i] = oldtype->disps[i]; - ntype->lengths[i] = oldtype->lengths[i]; - } + ntype->lengths = (int *)Utils::malloc(count * 2 * sizeof(int)); + ntype->disps = (int *)((char *)ntype->lengths + count * sizeof(int)); + for (i = 0; i < count; i++) { + ntype->disps[i] = oldtype->disps[i]; + ntype->lengths[i] = oldtype->lengths[i]; + } } /** Frees a fieldtype * @param ftype pointer to the type to be freed (Input) */ void halo_free_fieldtype(Fieldtype *ftype) { - if ((*ftype)->count>0) { + if ((*ftype)->count > 0) { free((*ftype)->lengths); (*ftype)->lengths = nullptr; } @@ -150,34 +150,34 @@ void halo_dtset(char *dest, int value, Fieldtype type) { int vblocks = type->vblocks; int vstride = type->vstride; - int vskip = type->vskip; - int count = type->count; - int *lens = type->lengths; - int *disps = type->disps; - int extent = type->extent; - - for (int i=0; ivskip; + int count = type->count; + int *lens = type->lengths; + int *disps = type->disps; + int extent = type->extent; + + for (int i = 0; i < vblocks; i++) { + for (int j = 0; j < vstride; j++) { s = dest; - for (int k=0; kvblocks; int vstride = type->vstride; - int vskip = type->vskip; - int extent = type->extent; + int vskip = type->vskip; + int extent = type->extent; HALO_TRACE(fprintf(stderr, "%d: halo_copy_vector %p %p vblocks=%d vstride=%d " "vskip=%d extent=%d subtype_extent=%d\n", @@ -190,11 +190,11 @@ void halo_copy_vector(char *r_buffer, char *s_buffer, int count, } for (i = 0; i < count; i++, s_buffer += extent, r_buffer += extent) { - for (j = 0, dest = r_buffer, src = s_buffer; jsubtype); + for (j = 0, dest = r_buffer, src = s_buffer; j < vblocks; + j++, dest += vskip, src += vskip) { + halo_dtcopy(dest, src, vstride, type->subtype); } } - } /** Copy lattice data with layout described by fieldtype. @@ -237,111 +237,111 @@ void halo_dtcopy(char *r_buffer, char *s_buffer, int count, Fieldtype type) { * @param fieldtype field layout of the lattice data (Input) * @param datatype MPI datatype for the lattice data (Input) */ -void prepare_halo_communication(HaloCommunicator *hc, Lattice *lattice, Fieldtype fieldtype, MPI_Datatype datatype) { - int k, n, dir, lr, cnt, num = 0 ; - int *grid = lattice->grid ; - int *period = lattice->halo_grid ; +void prepare_halo_communication(HaloCommunicator *hc, Lattice *lattice, + Fieldtype fieldtype, MPI_Datatype datatype) { + int k, n, dir, lr, cnt, num = 0; + int *grid = lattice->grid; + int *period = lattice->halo_grid; - for (n=0; nnum; n++) { + for (n = 0; n < hc->num; n++) { MPI_Type_free(&(hc->halo_info[n].datatype)); } - num = 2*3; /* two communications in each space direction */ + num = 2 * 3; /* two communications in each space direction */ - hc->num = num ; - hc->halo_info = Utils::realloc(hc->halo_info,num*sizeof(HaloInfo)) ; + hc->num = num; + hc->halo_info = Utils::realloc(hc->halo_info, num * sizeof(HaloInfo)); int extent = fieldtype->extent; - cnt = 0 ; - for (dir=0; dir<3; dir++) { - for (lr=0; lr<2; lr++) { - - HaloInfo *hinfo = &(hc->halo_info[cnt]) ; - - int nblocks = 1 ; - for (k=dir+1;k<3;k++) { - nblocks *= period[k] ; - } - int stride = 1 ; - for (k=0;ks_offset = extent * stride * 1; - hinfo->r_offset = extent * stride * (grid[dir]+1); - } else { - /* send to right, recv from left */ - hinfo->s_offset = extent * stride * grid[dir]; - hinfo->r_offset = extent * stride * 0; - - } - - hinfo->source_node = node_neighbors[2*dir+1-lr]; - hinfo->dest_node = node_neighbors[2*dir+lr]; - - halo_create_field_vector(nblocks, stride, skip, fieldtype, &hinfo->fieldtype); - - MPI_Type_vector(nblocks, stride, skip, datatype, &hinfo->datatype); - MPI_Type_commit(&hinfo->datatype); + cnt = 0; + for (dir = 0; dir < 3; dir++) { + for (lr = 0; lr < 2; lr++) { + + HaloInfo *hinfo = &(hc->halo_info[cnt]); + + int nblocks = 1; + for (k = dir + 1; k < 3; k++) { + nblocks *= period[k]; + } + int stride = 1; + for (k = 0; k < dir; k++) { + stride *= period[k]; + } + int skip = 1; + for (k = 0; k < dir + 1 && k < 2; k++) { + skip *= period[k]; + } + + if (lr == 0) { + /* send to left, recv from right */ + hinfo->s_offset = extent * stride * 1; + hinfo->r_offset = extent * stride * (grid[dir] + 1); + } else { + /* send to right, recv from left */ + hinfo->s_offset = extent * stride * grid[dir]; + hinfo->r_offset = extent * stride * 0; + } + + hinfo->source_node = node_neighbors[2 * dir + 1 - lr]; + hinfo->dest_node = node_neighbors[2 * dir + lr]; + + halo_create_field_vector(nblocks, stride, skip, fieldtype, + &hinfo->fieldtype); + + MPI_Type_vector(nblocks, stride, skip, datatype, &hinfo->datatype); + MPI_Type_commit(&hinfo->datatype); #ifdef PARTIAL_PERIODIC - if ( !PERIODIC(dir) && (boundary[2*dir+lr] != 0 || boundary[2*dir+1-lr] != 0) ) { - if (node_grid[dir] == 1) { - hinfo->type = HALO_OPEN; - } - else if (lr == 0) { - if (boundary[2*dir+lr] == 1) { - hinfo->type = HALO_RECV; - } else { - hinfo->type = HALO_SEND; - } - } - else { - if (boundary[2*dir+lr] == -1) { - hinfo->type = HALO_RECV; - } else { - hinfo->type = HALO_SEND; - } - } - } else + if (!PERIODIC(dir) && + (boundary[2 * dir + lr] != 0 || boundary[2 * dir + 1 - lr] != 0)) { + if (node_grid[dir] == 1) { + hinfo->type = HALO_OPEN; + } else if (lr == 0) { + if (boundary[2 * dir + lr] == 1) { + hinfo->type = HALO_RECV; + } else { + hinfo->type = HALO_SEND; + } + } else { + if (boundary[2 * dir + lr] == -1) { + hinfo->type = HALO_RECV; + } else { + hinfo->type = HALO_SEND; + } + } + } else #endif - { - if (node_grid[dir] == 1) { - hc->halo_info[cnt].type = HALO_LOCL; - } - else { - hc->halo_info[cnt].type = HALO_SENDRECV; - } - } - - HALO_TRACE(fprintf(stderr,"%d: prepare_halo_communication dir=%d lr=%d s_offset=%ld r_offset=%ld s_node=%d d_node=%d type=%d\n",this_node,dir,lr,hinfo->s_offset,hinfo->r_offset,hinfo->source_node,hinfo->dest_node,hinfo->type)) ; + { + if (node_grid[dir] == 1) { + hc->halo_info[cnt].type = HALO_LOCL; + } else { + hc->halo_info[cnt].type = HALO_SENDRECV; + } + } - cnt++; + HALO_TRACE(fprintf(stderr, "%d: prepare_halo_communication dir=%d lr=%d " + "s_offset=%ld r_offset=%ld s_node=%d " + "d_node=%d type=%d\n", + this_node, dir, lr, hinfo->s_offset, hinfo->r_offset, + hinfo->source_node, hinfo->dest_node, hinfo->type)); + cnt++; } } - } -/** Frees datastrutures associated with a halo communicator +/** Frees datastrutures associated with a halo communicator * @param hc halo communicator to be released */ void release_halo_communication(HaloCommunicator *hc) { int n; - for (n=0; nnum; n++) { + for (n = 0; n < hc->num; n++) { MPI_Type_free(&(hc->halo_info[n].datatype)); } free(hc->halo_info); - } /** Perform communication according to the parallelization scheme @@ -425,9 +425,7 @@ void halo_communication(HaloCommunicator *hc, char *base) { halo_dtset(r_buffer, 0, fieldtype); break; } - - } - + } } #endif /* LATTICE */ diff --git a/src/core/halo.hpp b/src/core/halo.hpp index 38284883b9..0ae61c5fe1 100755 --- a/src/core/halo.hpp +++ b/src/core/halo.hpp @@ -1,26 +1,26 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -/** \file halo.hpp - * - * Halo scheme for parallelization of lattice algorithms. +/** \file halo.hpp + * + * Halo scheme for parallelization of lattice algorithms. * Header file for \ref halo.cpp. * */ @@ -28,9 +28,9 @@ #ifndef _HALO_HPP #define _HALO_HPP -#include -#include "utils.hpp" #include "lattice.hpp" +#include "utils.hpp" +#include #ifdef LATTICE @@ -42,12 +42,14 @@ * */ /*@{*/ -#define HALO_LOCL 0 /**< Tag for local exchange of halo regions on the same processor */ -#define HALO_SENDRECV 1 /**< Tag for halo exchange between different processors */ -#define HALO_SEND 2 /**< Tag for halo send only */ -#define HALO_RECV 3 /**< Tag for halo receive only */ -#define HALO_OPEN 4 /**< Tag for halo open boundary */ -/*@}*/ +#define HALO_LOCL \ + 0 /**< Tag for local exchange of halo regions on the same processor */ +#define HALO_SENDRECV \ + 1 /**< Tag for halo exchange between different processors */ +#define HALO_SEND 2 /**< Tag for halo send only */ +#define HALO_RECV 3 /**< Tag for halo receive only */ +#define HALO_OPEN 4 /**< Tag for halo open boundary */ + /*@}*/ /** \name Tags for halo communications *
@@ -58,8 +60,8 @@ */ /*@{*/ #define REQ_HALO_SPREAD 501 /**< Tag for halo update */ -#define REQ_HALO_CHECK 599 /**< Tag for consistency check of halo regions */ -/*@}*/ +#define REQ_HALO_CHECK 599 /**< Tag for consistency check of halo regions */ + /*@}*/ /** This struct describes the layout of the lattice data. The description * is similar to MPI datatypes but a bit more compact. See \ref @@ -85,50 +87,53 @@ extern struct _Fieldtype fieldtype_double; /** Structure describing a Halo region */ typedef struct { - int type; /**< type of halo communication */ + int type; /**< type of halo communication */ - int source_node; /**< index of processor which sends halo data */ - int dest_node; /**< index of processor receiving halo data */ + int source_node; /**< index of processor which sends halo data */ + int dest_node; /**< index of processor receiving halo data */ - //void *send_buffer; /**< pointer to data being sent */ - //void *recv_buffer; /**< pointer to data being received */ + // void *send_buffer; /**< pointer to data being sent */ + // void *recv_buffer; /**< pointer to data being received */ unsigned long s_offset; /**< offset for send buffer */ unsigned long r_offset; /**< offset for receive buffer */ - Fieldtype fieldtype; /**< type layout of the data beeing exchanged */ - MPI_Datatype datatype; /**< MPI datatype of data beeing communicated */ + Fieldtype fieldtype; /**< type layout of the data beeing exchanged */ + MPI_Datatype datatype; /**< MPI datatype of data beeing communicated */ -} HaloInfo ; +} HaloInfo; /** Structure holding a set of \ref HaloInfo which comprise a certain * parallelization scheme */ typedef struct { - int num; /**< number of halo communications in the scheme */ + int num; /**< number of halo communications in the scheme */ HaloInfo *halo_info; /**< set of halo communications */ } HaloCommunicator; -/** Creates a fieldtype describing the data layout +/** Creates a fieldtype describing the data layout * @param count number of subtypes (Input) * @param lengths array of lenghts of the subtytpes (Input) * @param disps array of displacements the subtypes (Input) * @param extent extent of the whole new fieldtype (Input) * @param newtype newly created fieldtype (Input/Output) */ -void halo_create_fieldtype(int count, int *lengths, int *disps, int extent, Fieldtype *newtype); +void halo_create_fieldtype(int count, int *lengths, int *disps, int extent, + Fieldtype *newtype); /** Creates a field vector layout - * @param vblocks number of vector blocks(Input) + * @param vblocks number of vector blocks(Input) * @param vstride size of strides in field vector (Input) * @param vskip displacements of strides in field vector (Input) * @param oldtype fieldtype the vector is composed of (Input) * @param newtype newly created fieldtype (Input/Output) */ -void halo_create_field_vector(int vblocks, int vstride, int vskip, Fieldtype oldtype, Fieldtype *newtype); -void halo_create_field_hvector(int vblocks, int vstride, int vskip, Fieldtype oldtype, Fieldtype *newtype); +void halo_create_field_vector(int vblocks, int vstride, int vskip, + Fieldtype oldtype, Fieldtype *newtype); +void halo_create_field_hvector(int vblocks, int vstride, int vskip, + Fieldtype oldtype, Fieldtype *newtype); /** Frees a fieldtype * @param ftype pointer to the type to be freed (Input) @@ -142,9 +147,10 @@ void halo_free_fieldtype(Fieldtype *ftype); * @param fieldtype field layout of the lattice data (Input) * @param datatype MPI datatype for the lattice data (Input) */ -void prepare_halo_communication(HaloCommunicator *hc, Lattice *lattice, Fieldtype fieldtype, MPI_Datatype datatype); +void prepare_halo_communication(HaloCommunicator *hc, Lattice *lattice, + Fieldtype fieldtype, MPI_Datatype datatype); -/** Frees datastrutures associated with a halo communicator +/** Frees datastrutures associated with a halo communicator * @param hc halo communicator to be released */ void release_halo_communication(HaloCommunicator *hc); diff --git a/src/core/harmonic.cpp b/src/core/harmonic.cpp index f148802538..19b7d9d778 100755 --- a/src/core/harmonic.cpp +++ b/src/core/harmonic.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file harmonic.cpp * @@ -25,9 +25,8 @@ #include "harmonic.hpp" #include "communication.hpp" -int harmonic_set_params(int bond_type, double k, double r,double r_cut) -{ - if(bond_type < 0) +int harmonic_set_params(int bond_type, double k, double r, double r_cut) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -36,10 +35,10 @@ int harmonic_set_params(int bond_type, double k, double r,double r_cut) bonded_ia_params[bond_type].p.harmonic.r = r; bonded_ia_params[bond_type].p.harmonic.r_cut = r_cut; bonded_ia_params[bond_type].type = BONDED_IA_HARMONIC; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/harmonic.hpp b/src/core/harmonic.hpp index 026c67033c..bdff74201f 100755 --- a/src/core/harmonic.hpp +++ b/src/core/harmonic.hpp @@ -1,94 +1,106 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _HARMONIC_HPP #define _HARMONIC_HPP /** \file harmonic.hpp - * Routines to calculate the HARMONIC Energy or/and HARMONIC force + * Routines to calculate the HARMONIC Energy or/and HARMONIC force * for a particle pair. * \ref forces.cpp */ /************************************************************/ -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" #include "random.hpp" +#include "utils.hpp" /// set the parameters for the harmonic potential -int harmonic_set_params(int bond_type, double k, double r,double r_cut); +int harmonic_set_params(int bond_type, double k, double r, double r_cut); /** Computes the HARMONIC pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. - @param iaparams bond type number of the angle interaction (see \ref interaction_data.cpp). + @param iaparams bond type number of the angle interaction (see \ref + interaction_data.cpp). @param dx particle distance vector @param force returns force of particle 1 @return 0. */ -inline int calc_harmonic_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force[3]) -{ +inline int calc_harmonic_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double force[3]) { int i; double fac; double dist2 = sqrlen(dx); double dist = sqrt(dist2); double dr; - if ((iaparams->p.harmonic.r_cut > 0.0) && - (dist > iaparams->p.harmonic.r_cut)) + if ((iaparams->p.harmonic.r_cut > 0.0) && (dist > iaparams->p.harmonic.r_cut)) return 1; dr = dist - iaparams->p.harmonic.r; fac = -iaparams->p.harmonic.k * dr; if (fabs(dr) > ROUND_ERROR_PREC) { - if(dist>ROUND_ERROR_PREC) { /* Regular case */ - fac /= dist; - } else { /* dx[] == 0: the force is undefined. Let's use a random direction */ - for(i=0;i<3;i++) dx[i] = d_random()-0.5; - fac /= sqrt(sqrlen(dx)); - } - } else { - fac=0; + if (dist > ROUND_ERROR_PREC) { /* Regular case */ + fac /= dist; + } else { /* dx[] == 0: the force is undefined. Let's use a random direction + */ + for (i = 0; i < 3; i++) + dx[i] = d_random() - 0.5; + fac /= sqrt(sqrlen(dx)); + } + } else { + fac = 0; } - - for(i=0;i<3;i++) - force[i] = fac*dx[i]; - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist2,fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist2,fac)); + + for (i = 0; i < 3; i++) + force[i] = fac * dx[i]; + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, dist2, fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, dist2, fac)); return 0; } -inline int harmonic_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ +inline int harmonic_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, double dx[3], + double *_energy) { double dist2 = sqrlen(dx); double dist = sqrt(dist2); - if ((iaparams->p.harmonic.r_cut > 0.0) && - (dist > iaparams->p.harmonic.r_cut)) + if ((iaparams->p.harmonic.r_cut > 0.0) && (dist > iaparams->p.harmonic.r_cut)) return 1; - *_energy = 0.5*iaparams->p.harmonic.k*Utils::sqr(dist - iaparams->p.harmonic.r); + *_energy = + 0.5 * iaparams->p.harmonic.k * Utils::sqr(dist - iaparams->p.harmonic.r); return 0; } diff --git a/src/core/harmonic_dumbbell.cpp b/src/core/harmonic_dumbbell.cpp index 6e444432a9..33319bac8f 100644 --- a/src/core/harmonic_dumbbell.cpp +++ b/src/core/harmonic_dumbbell.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file harmonic_dumbbell.cpp * @@ -27,22 +27,22 @@ #ifdef ROTATION -int harmonic_dumbbell_set_params(int bond_type, double k1, double k2, double r, double r_cut) -{ - if(bond_type < 0) +int harmonic_dumbbell_set_params(int bond_type, double k1, double k2, double r, + double r_cut) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); - bonded_ia_params[bond_type].p.harmonic_dumbbell.k1 = k1; - bonded_ia_params[bond_type].p.harmonic_dumbbell.k2 = k2; - bonded_ia_params[bond_type].p.harmonic_dumbbell.r = r; - bonded_ia_params[bond_type].p.harmonic_dumbbell.r_cut = r_cut; + bonded_ia_params[bond_type].p.harmonic_dumbbell.k1 = k1; + bonded_ia_params[bond_type].p.harmonic_dumbbell.k2 = k2; + bonded_ia_params[bond_type].p.harmonic_dumbbell.r = r; + bonded_ia_params[bond_type].p.harmonic_dumbbell.r_cut = r_cut; bonded_ia_params[bond_type].type = BONDED_IA_HARMONIC_DUMBBELL; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/harmonic_dumbbell.hpp b/src/core/harmonic_dumbbell.hpp index ab55b92c12..5a2c285f81 100644 --- a/src/core/harmonic_dumbbell.hpp +++ b/src/core/harmonic_dumbbell.hpp @@ -1,27 +1,27 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _HARMONIC_DUMBBELL_HPP #define _HARMONIC_DUMBBELL_HPP /** \file harmonic_dumbbell.hpp - * Routines to calculate the HARMONIC Energy or/and HARMONIC force + * Routines to calculate the HARMONIC Energy or/and HARMONIC force * for a particle pair. * \ref forces.cpp */ @@ -29,91 +29,103 @@ /************************************************************/ #include "debug.hpp" -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" #include "random.hpp" +#include "utils.hpp" #ifdef ROTATION /// set the parameters for the harmonic potential -int harmonic_dumbbell_set_params(int bond_type, double k1, double k2, double r, double r_cut); +int harmonic_dumbbell_set_params(int bond_type, double k1, double k2, double r, + double r_cut); /** Computes the HARMONIC pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. - @param iaparams bond type number of the angle interaction (see \ref interaction_data.cpp). + @param iaparams bond type number of the angle interaction (see \ref + interaction_data.cpp). @param dx particle distance vector @param force returns force of particle 1 @return 0. */ -inline int calc_harmonic_dumbbell_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force[3]) -{ +inline int calc_harmonic_dumbbell_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double force[3]) { double fac; double dist2 = sqrlen(dx); double dist = sqrt(dist2); double dr; if ((iaparams->p.harmonic_dumbbell.r_cut > 0.0) && - (dist > iaparams->p.harmonic_dumbbell.r_cut)) + (dist > iaparams->p.harmonic_dumbbell.r_cut)) return 1; dr = dist - iaparams->p.harmonic_dumbbell.r; fac = -iaparams->p.harmonic_dumbbell.k1 * dr; if (fabs(dr) > ROUND_ERROR_PREC) { - if (dist > ROUND_ERROR_PREC) /* Regular case */ - fac /= dist; - else { /* dx[] == 0: the force is undefined. Let's use a random direction */ - for(int i=0;i<3;i++) - dx[i] = d_random()-0.5; - fac /= sqrt(sqrlen(dx)); - } - } else { - fac = 0; + if (dist > ROUND_ERROR_PREC) /* Regular case */ + fac /= dist; + else { /* dx[] == 0: the force is undefined. Let's use a random direction */ + for (int i = 0; i < 3; i++) + dx[i] = d_random() - 0.5; + fac /= sqrt(sqrlen(dx)); + } + } else { + fac = 0; } - - for (int i=0; i<3; i++) - force[i] = fac*dx[i]; + + for (int i = 0; i < 3; i++) + force[i] = fac * dx[i]; double dhat[3]; - dhat[0] = dx[0]/dist; - dhat[1] = dx[1]/dist; - dhat[2] = dx[2]/dist; + dhat[0] = dx[0] / dist; + dhat[1] = dx[1] / dist; + dhat[2] = dx[2] / dist; double da[3]; - da[0] = dhat[1]*p1->r.quatu[2] - dhat[2]*p1->r.quatu[1]; - da[1] = dhat[2]*p1->r.quatu[0] - dhat[0]*p1->r.quatu[2]; - da[2] = dhat[0]*p1->r.quatu[1] - dhat[1]*p1->r.quatu[0]; + da[0] = dhat[1] * p1->r.quatu[2] - dhat[2] * p1->r.quatu[1]; + da[1] = dhat[2] * p1->r.quatu[0] - dhat[0] * p1->r.quatu[2]; + da[2] = dhat[0] * p1->r.quatu[1] - dhat[1] * p1->r.quatu[0]; p1->f.torque[0] += iaparams->p.harmonic_dumbbell.k2 * da[0]; p1->f.torque[1] += iaparams->p.harmonic_dumbbell.k2 * da[1]; p1->f.torque[2] += iaparams->p.harmonic_dumbbell.k2 * da[2]; - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist2,fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist2,fac)); + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, dist2, fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: HARMONIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, dist2, fac)); return 0; } -inline int harmonic_dumbbell_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ +inline int harmonic_dumbbell_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double *_energy) { double dist2 = sqrlen(dx); double dist = sqrt(dist2); - if ((iaparams->p.harmonic_dumbbell.r_cut > 0.0) && - (dist > iaparams->p.harmonic_dumbbell.r_cut)) + if ((iaparams->p.harmonic_dumbbell.r_cut > 0.0) && + (dist > iaparams->p.harmonic_dumbbell.r_cut)) return 1; double dhat[3]; - dhat[0] = dx[0]/dist; - dhat[1] = dx[1]/dist; - dhat[2] = dx[2]/dist; + dhat[0] = dx[0] / dist; + dhat[1] = dx[1] / dist; + dhat[2] = dx[2] / dist; double da[3]; - da[0] = dhat[1]*p1->r.quatu[2] - dhat[2]*p1->r.quatu[1]; - da[1] = dhat[2]*p1->r.quatu[0] - dhat[0]*p1->r.quatu[2]; - da[2] = dhat[0]*p1->r.quatu[1] - dhat[1]*p1->r.quatu[0]; + da[0] = dhat[1] * p1->r.quatu[2] - dhat[2] * p1->r.quatu[1]; + da[1] = dhat[2] * p1->r.quatu[0] - dhat[0] * p1->r.quatu[2]; + da[2] = dhat[0] * p1->r.quatu[1] - dhat[1] * p1->r.quatu[0]; double torque[3]; torque[0] = iaparams->p.harmonic_dumbbell.k2 * da[0]; @@ -125,8 +137,11 @@ inline int harmonic_dumbbell_pair_energy(Particle *p1, Particle *p2, Bonded_ia_p diff[1] = dhat[1] - p1->r.quatu[1]; diff[2] = dhat[2] - p1->r.quatu[2]; - *_energy = 0.5*iaparams->p.harmonic_dumbbell.k1*Utils::sqr(dist - iaparams->p.harmonic.r) - + 0.5*iaparams->p.harmonic_dumbbell.k2*(torque[0]*diff[0] + torque[1]*diff[1] + torque[2]*diff[2]); + *_energy = + 0.5 * iaparams->p.harmonic_dumbbell.k1 * + Utils::sqr(dist - iaparams->p.harmonic.r) + + 0.5 * iaparams->p.harmonic_dumbbell.k2 * + (torque[0] * diff[0] + torque[1] * diff[1] + torque[2] * diff[2]); return 0; } diff --git a/src/core/hat.cpp b/src/core/hat.cpp index d525094a00..df31141ee0 100755 --- a/src/core/hat.cpp +++ b/src/core/hat.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file soft_sphere.cpp * @@ -27,18 +27,17 @@ #ifdef HAT -#include "hat.hpp" #include "communication.hpp" +#include "hat.hpp" -int hat_set_params(int part_type_a, int part_type_b, - double Fmax, double r) -{ +int hat_set_params(int part_type_a, int part_type_b, double Fmax, double r) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; data->HAT_Fmax = Fmax; - data->HAT_r = r; + data->HAT_r = r; /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); diff --git a/src/core/hat.hpp b/src/core/hat.hpp index 8beb09b8ad..dbc135dc41 100755 --- a/src/core/hat.hpp +++ b/src/core/hat.hpp @@ -31,10 +31,10 @@ #ifdef HAT -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" /// int hat_set_params(int part_type_a, int part_type_b, double Fmax, double r); diff --git a/src/core/hertzian.cpp b/src/core/hertzian.cpp index bedb16a0f9..ecc1d24b9b 100755 --- a/src/core/hertzian.cpp +++ b/src/core/hertzian.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file hertzian.cpp * @@ -27,13 +27,13 @@ #ifdef HERTZIAN -int hertzian_set_params(int part_type_a, int part_type_b, - double eps, double sig) -{ +int hertzian_set_params(int part_type_a, int part_type_b, double eps, + double sig) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) return ES_ERROR; - + + if (!data) + return ES_ERROR; + data->Hertzian_eps = eps; data->Hertzian_sig = sig; diff --git a/src/core/hertzian.hpp b/src/core/hertzian.hpp index d7deef8d2e..4c211a18d4 100755 --- a/src/core/hertzian.hpp +++ b/src/core/hertzian.hpp @@ -27,9 +27,9 @@ * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef HERTZIAN @@ -45,7 +45,7 @@ inline void add_hertzian_pair_force(const Particle *const p1, double force[3]) { if ((dist < ia_params->Hertzian_sig)) { double fac = 5. / 2. * ia_params->Hertzian_eps / ia_params->Hertzian_sig * - pow(1 - dist / ia_params->Hertzian_sig, 3. / 2.) / dist; + pow(1 - dist / ia_params->Hertzian_sig, 3. / 2.) / dist; for (int j = 0; j < 3; j++) force[j] += fac * d[j]; diff --git a/src/core/iccp3m.cpp b/src/core/iccp3m.cpp index 7cb3615b3e..d540122189 100755 --- a/src/core/iccp3m.cpp +++ b/src/core/iccp3m.cpp @@ -44,10 +44,10 @@ #include "config.hpp" #include "forces.hpp" #include "global.hpp" +#include "initialize.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" #include "utils.hpp" -#include "initialize.hpp" #include "short_range_loop.hpp" #include "utils/NoOp.hpp" @@ -208,8 +208,8 @@ int bcast_iccp3m_cfg(void) { } int iccp3m_iteration() { - double fdot, hold, hnew, del_eps, diff = 0.0, difftemp = 0.0, ex, ey, - ez, pref; + double fdot, hold, hnew, del_eps, diff = 0.0, difftemp = 0.0, ex, ey, ez, + pref; Cell *cell; int c, np; Particle *part; @@ -261,7 +261,6 @@ int iccp3m_iteration() { msg << "ICCP3M found zero electric field on a charge. This must " "never happen"; runtimeError(msg); - } /* the dot product */ fdot = ex * iccp3m_cfg.nvectorx[id] + ey * iccp3m_cfg.nvectory[id] + @@ -330,21 +329,22 @@ int iccp3m_iteration() { void force_calc_iccp3m() { init_forces_iccp3m(); - short_range_loop(Utils::NoOp{}, [](Particle &p1, Particle &p2, Distance &d) { - /* calc non bonded interactions */ - add_non_bonded_pair_force_iccp3m(&(p1), &(p2), d.vec21.data(), sqrt(d.dist2), - d.dist2); - }); + short_range_loop(Utils::NoOp{}, + [](Particle &p1, Particle &p2, Distance &d) { + /* calc non bonded interactions */ + add_non_bonded_pair_force_iccp3m( + &(p1), &(p2), d.vec21.data(), sqrt(d.dist2), d.dist2); + }); calc_long_range_forces_iccp3m(); } void init_forces_iccp3m() { - for(auto & p : local_cells.particles()) { + for (auto &p : local_cells.particles()) { p.f = ParticleForce{}; } - for(auto & p : ghost_cells.particles()) { + for (auto &p : ghost_cells.particles()) { p.f = ParticleForce{}; } } diff --git a/src/core/immersed_boundaries.cpp b/src/core/immersed_boundaries.cpp index c61ad24ead..5338022feb 100644 --- a/src/core/immersed_boundaries.cpp +++ b/src/core/immersed_boundaries.cpp @@ -1,4 +1,4 @@ -#include "immersed_boundaries.hpp" +#include "immersed_boundaries.hpp" #ifdef IMMERSED_BOUNDARY diff --git a/src/core/immersed_boundaries.hpp b/src/core/immersed_boundaries.hpp index a0307b2c92..c092785d13 100644 --- a/src/core/immersed_boundaries.hpp +++ b/src/core/immersed_boundaries.hpp @@ -1,13 +1,10 @@ #ifndef IMMERSED_BOUNDARIES_HPP #define IMMERSED_BOUNDARIES_HPP -#include "config.hpp" +#include "config.hpp" #include "immersed_boundary/ImmersedBoundaries.hpp" - - #ifdef IMMERSED_BOUNDARY extern ImmersedBoundaries immersed_boundaries; #endif #endif - diff --git a/src/core/immersed_boundary/ImmersedBoundaries.cpp b/src/core/immersed_boundary/ImmersedBoundaries.cpp index 59f9cd54a4..d97379a350 100644 --- a/src/core/immersed_boundary/ImmersedBoundaries.cpp +++ b/src/core/immersed_boundary/ImmersedBoundaries.cpp @@ -3,16 +3,12 @@ #ifdef IMMERSED_BOUNDARY -#include "particle_data.hpp" -#include "interaction_data.hpp" -#include "grid.hpp" +#include "ImmersedBoundaries.hpp" #include "cells.hpp" #include "communication.hpp" -#include "ImmersedBoundaries.hpp" - - - - +#include "grid.hpp" +#include "interaction_data.hpp" +#include "particle_data.hpp" /************ IBM_VolumeConservation @@ -20,74 +16,70 @@ Calculate (1) volumes, (2) volume force and (3) add it to each virtual particle This function is called from integrate_vv **************/ -void ImmersedBoundaries::volume_conservation() -{ +void ImmersedBoundaries::volume_conservation() { // Calculate volumes calc_volumes(); - + calc_volume_force(); - + // Center-of-mass output - //if ( numWriteCOM > 0 ) -// IBM_CalcCentroids(frameNum, simTime); + // if ( numWriteCOM > 0 ) + // IBM_CalcCentroids(frameNum, simTime); } /************ IBM_InitVolumeConservation *************/ -void ImmersedBoundaries::init_volume_conservation() -{ - +void ImmersedBoundaries::init_volume_conservation() { + // Check since this function is called at the start of every integrate loop // Also check if volume has been set due to reading of a checkpoint - if ( !VolumeInitDone ) - { - + if (!VolumeInitDone) { + // Calculate volumes calc_volumes(); - - //numWriteCOM = 0; - - // Loop through all bonded interactions and check if we need to set the reference volume - for (int i=0; i < bonded_ia_params.size(); i++) - { - if ( bonded_ia_params[i].type == BONDED_IA_IBM_VOLUME_CONSERVATION ) - { - // This check is important because InitVolumeConservation may be called accidentally + + // numWriteCOM = 0; + + // Loop through all bonded interactions and check if we need to set the + // reference volume + for (int i = 0; i < bonded_ia_params.size(); i++) { + if (bonded_ia_params[i].type == BONDED_IA_IBM_VOLUME_CONSERVATION) { + // This check is important because InitVolumeConservation may be called + // accidentally // during the integration. Then we must not reset the reference - if ( bonded_ia_params[i].p.ibmVolConsParameters.volRef == 0 ) - { - const int softID =bonded_ia_params[i].p.ibmVolConsParameters.softID; - bonded_ia_params[i].p.ibmVolConsParameters.volRef = VolumesCurrent[softID]; + if (bonded_ia_params[i].p.ibmVolConsParameters.volRef == 0) { + const int softID = bonded_ia_params[i].p.ibmVolConsParameters.softID; + bonded_ia_params[i].p.ibmVolConsParameters.volRef = + VolumesCurrent[softID]; } } - } - } - + VolumeInitDone = true; - } - /**************** IBM_VolumeConservation_ResetParams *****************/ -int ImmersedBoundaries::volume_conservation_reset_params(const int bond_type, const double volRef) -{ - +int ImmersedBoundaries::volume_conservation_reset_params(const int bond_type, + const double volRef) { + // Check if bond exists and is of correct type - if ( bond_type >= bonded_ia_params.size() ) return ES_ERROR; - if ( bonded_ia_params[bond_type].type != BONDED_IA_IBM_VOLUME_CONSERVATION ) return ES_ERROR; - + if (bond_type >= bonded_ia_params.size()) + return ES_ERROR; + if (bonded_ia_params[bond_type].type != BONDED_IA_IBM_VOLUME_CONSERVATION) + return ES_ERROR; + // Specific stuff - // We need to set this here, since it is not re-calculated at the restarting of a sim as, e.g., triel + // We need to set this here, since it is not re-calculated at the restarting + // of a sim as, e.g., triel bonded_ia_params[bond_type].p.ibmVolConsParameters.volRef = volRef; - - //Communicate this to whoever is interested + + // Communicate this to whoever is interested mpi_bcast_ia_params(bond_type, -1); return ES_OK; @@ -97,29 +89,40 @@ int ImmersedBoundaries::volume_conservation_reset_params(const int bond_type, co IBM_VolumeConservation_SetParams ************/ -int ImmersedBoundaries::volume_conservation_set_params(const int bond_type, const int softID, const double kappaV) -{ +int ImmersedBoundaries::volume_conservation_set_params(const int bond_type, + const int softID, + const double kappaV) { // Create bond make_bond_type_exist(bond_type); - + // General bond parameters bonded_ia_params[bond_type].type = BONDED_IA_IBM_VOLUME_CONSERVATION; - bonded_ia_params[bond_type].num = 0; // This means that Espresso requires one bond partner. Here we simply ignore it, but Espresso cannot handle 0. - + bonded_ia_params[bond_type].num = 0; // This means that Espresso requires one + // bond partner. Here we simply ignore + // it, but Espresso cannot handle 0. + // Specific stuff - if ( softID > MaxNumIBM) { printf("Error: softID (%d) is larger than MaxNumIBM (%d)\n", softID, MaxNumIBM); return ES_ERROR; } - if ( softID < 0) { printf("Error: softID (%d) must be non-negative\n", softID); return ES_ERROR; } - + if (softID > MaxNumIBM) { + printf("Error: softID (%d) is larger than MaxNumIBM (%d)\n", softID, + MaxNumIBM); + return ES_ERROR; + } + if (softID < 0) { + printf("Error: softID (%d) must be non-negative\n", softID); + return ES_ERROR; + } + bonded_ia_params[bond_type].p.ibmVolConsParameters.softID = softID; bonded_ia_params[bond_type].p.ibmVolConsParameters.kappaV = kappaV; bonded_ia_params[bond_type].p.ibmVolConsParameters.volRef = 0; - // NOTE: We cannot compute the reference volume here because not all interactions are setup + // NOTE: We cannot compute the reference volume here because not all + // interactions are setup // and thus we do not know which triangles belong to this softID // Calculate it later in the init function - - //Communicate this to whoever is interested + + // Communicate this to whoever is interested mpi_bcast_ia_params(bond_type, -1); - + return ES_OK; } @@ -129,123 +132,131 @@ Calculate partial volumes on all compute nodes and call MPI to sum up ****************/ -void ImmersedBoundaries::calc_volumes() -{ - +void ImmersedBoundaries::calc_volumes() { + // Partial volumes for each soft particle, to be summed up std::vector tempVol(MaxNumIBM); - + // Loop over all particles on local node - for (int c = 0; c < local_cells.n; c++) - { + for (int c = 0; c < local_cells.n; c++) { const Cell *const cell = local_cells.cell[c]; - - for (int i = 0; i < cell->n; i++) - { + + for (int i = 0; i < cell->n; i++) { Particle &p1 = cell->part[i]; - - // Check if particle has a BONDED_IA_IBM_TRIEL and a BONDED_IA_IBM_VOLUME_CONSERVATION + + // Check if particle has a BONDED_IA_IBM_TRIEL and a + // BONDED_IA_IBM_VOLUME_CONSERVATION // Basically this loops over all triangles, not all particles // First round to check for volume conservation and virtual // Loop over all bonds of this particle - // Actually j loops over the bond-list, i.e. the bond partners (see particle_data.hpp) + // Actually j loops over the bond-list, i.e. the bond partners (see + // particle_data.hpp) int softID = -1; int j = 0; - while ( j < p1.bl.n ) - { + while (j < p1.bl.n) { const int type_num = p1.bl.e[j]; const Bonded_ia_parameters &iaparams = bonded_ia_params[type_num]; const int type = iaparams.type; - if ( type == BONDED_IA_IBM_VOLUME_CONSERVATION ) - { - if ( p1.p.is_virtual) softID = iaparams.p.ibmVolConsParameters.softID; - else { printf("Error. Encountered non-virtual particle with VOLUME_CONSERVATION_IBM\n"); exit(1); } + if (type == BONDED_IA_IBM_VOLUME_CONSERVATION) { + if (p1.p.is_virtual) + softID = iaparams.p.ibmVolConsParameters.softID; + else { + printf("Error. Encountered non-virtual particle with " + "VOLUME_CONSERVATION_IBM\n"); + exit(1); + } } - // Iterate, increase by the number of partners of this bond + 1 for bond type - j += iaparams.num+1; + // Iterate, increase by the number of partners of this bond + 1 for bond + // type + j += iaparams.num + 1; } - - + // Second round for triel - if ( softID > -1 ) - { + if (softID > -1) { j = 0; - while ( j < p1.bl.n) - { + while (j < p1.bl.n) { const int type_num = p1.bl.e[j]; const Bonded_ia_parameters &iaparams = bonded_ia_params[type_num]; const int type = iaparams.type; - - if ( type == BONDED_IA_IBM_TRIEL ) - { + + if (type == BONDED_IA_IBM_TRIEL) { // Our particle is the leading particle of a triel // Get second and third particle of the triangle - Particle *p2 = local_particles[p1.bl.e[j+1]]; - if (!p2) - { - runtimeErrorMsg() << "{IBM_calc_volumes: 078 bond broken between particles " - << p1.p.identity << " and " << p1.bl.e[j+1] << " (particles not stored on the same node)} "; + Particle *p2 = local_particles[p1.bl.e[j + 1]]; + if (!p2) { + runtimeErrorMsg() + << "{IBM_calc_volumes: 078 bond broken between particles " + << p1.p.identity << " and " << p1.bl.e[j + 1] + << " (particles not stored on the same node)} "; return; } - Particle *p3 = local_particles[p1.bl.e[j+2]]; - if (!p3) - { - runtimeErrorMsg() << "{IBM_calc_volumes: 078 bond broken between particles " - << p1.p.identity << " and " << p1.bl.e[j+2] << " (particles not stored on the same node)} "; + Particle *p3 = local_particles[p1.bl.e[j + 2]]; + if (!p3) { + runtimeErrorMsg() + << "{IBM_calc_volumes: 078 bond broken between particles " + << p1.p.identity << " and " << p1.bl.e[j + 2] + << " (particles not stored on the same node)} "; return; } - + // Unfold position of first node - // this is to get a continuous trajectory with no jumps when box boundaries are crossed - double x1[3] = { p1.r.p[0], p1.r.p[1], p1.r.p[2] }; - int img[3] = { p1.l.i[0], p1.l.i[1], p1.l.i[2] }; - unfold_position(x1,img); - + // this is to get a continuous trajectory with no jumps when box + // boundaries are crossed + double x1[3] = {p1.r.p[0], p1.r.p[1], p1.r.p[2]}; + int img[3] = {p1.l.i[0], p1.l.i[1], p1.l.i[2]}; + unfold_position(x1, img); + // Unfolding seems to work only for the first particle of a triel // so get the others from relative vectors considering PBC double a12[3]; get_mi_vector(a12, p2->r.p, x1); double a13[3]; get_mi_vector(a13, p3->r.p, x1); - + double x2[3]; double x3[3]; - - for (int i=0; i < 3; i++) - { + + for (int i = 0; i < 3; i++) { x2[i] = x1[i] + a12[i]; x3[i] = x1[i] + a13[i]; } - + // Volume of this tetrahedron // See Cha Zhang et.al. 2001, doi:10.1109/ICIP.2001.958278 // http://research.microsoft.com/en-us/um/people/chazhang/publications/icip01_ChaZhang.pdf - // The volume can be negative, but it is not necessarily the "signed volume" in the above paper - // (the sign of the real "signed volume" must be calculated using the normal vector; the result of the calculation here - // is simply a term in the sum required to calculate the volume of a particle). Again, see the paper. - // This should be equivalent to the formulation using vector identities in Krüger thesis - + // The volume can be negative, but it is not necessarily the "signed + // volume" in the above paper + // (the sign of the real "signed volume" must be calculated using + // the normal vector; the result of the calculation here + // is simply a term in the sum required to calculate the volume of a + // particle). Again, see the paper. + // This should be equivalent to the formulation using vector + // identities in Krüger thesis + const double v321 = x3[0] * x2[1] * x1[2]; const double v231 = x2[0] * x3[1] * x1[2]; const double v312 = x3[0] * x1[1] * x2[2]; const double v132 = x1[0] * x3[1] * x2[2]; const double v213 = x2[0] * x1[1] * x3[2]; const double v123 = x1[0] * x2[1] * x3[2]; - - tempVol[softID] += 1.0/6.0 * (-v321 + v231 + v312 - v132 - v213 + v123); + + tempVol[softID] += + 1.0 / 6.0 * (-v321 + v231 + v312 - v132 - v213 + v123); } - // Iterate, increase by the number of partners of this bond + 1 for bond type - j += iaparams.num+1; + // Iterate, increase by the number of partners of this bond + 1 for + // bond type + j += iaparams.num + 1; } } } } - - for (int i = 0; i < MaxNumIBM; i++) VolumesCurrent[i] = 0; - + + for (int i = 0; i < MaxNumIBM; i++) + VolumesCurrent[i] = 0; + // Sum up and communicate - MPI_Allreduce(&(tempVol.front()), &(VolumesCurrent.front()), MaxNumIBM, MPI_DOUBLE, MPI_SUM, comm_cart); - + MPI_Allreduce(&(tempVol.front()), &(VolumesCurrent.front()), MaxNumIBM, + MPI_DOUBLE, MPI_SUM, comm_cart); } /***************** @@ -253,89 +264,87 @@ void ImmersedBoundaries::calc_volumes() Calculate and add the volume force to each node *******************/ -void ImmersedBoundaries::calc_volume_force() -{ +void ImmersedBoundaries::calc_volume_force() { // Loop over all particles on local node - for (int c = 0; c < local_cells.n; c++) - { + for (int c = 0; c < local_cells.n; c++) { const Cell *const cell = local_cells.cell[c]; - - for (int i = 0; i < cell->n; i++) - { + + for (int i = 0; i < cell->n; i++) { Particle &p1 = cell->part[i]; - - // Check if particle has a BONDED_IA_IBM_TRIEL and a BONDED_IA_IBM_VOLUME_CONSERVATION + + // Check if particle has a BONDED_IA_IBM_TRIEL and a + // BONDED_IA_IBM_VOLUME_CONSERVATION // Basically this loops over all triangles, not all particles // First round to check for volume conservation and virtual // Loop over all bonds of this particle - // Actually j loops over the bond-list, i.e. the bond partners (see particle_data.hpp) + // Actually j loops over the bond-list, i.e. the bond partners (see + // particle_data.hpp) int softID = -1; double volRef = 0.; double kappaV = 0.; int j = 0; - while ( j < p1.bl.n ) - { + while (j < p1.bl.n) { const int type_num = p1.bl.e[j]; const Bonded_ia_parameters &iaparams = bonded_ia_params[type_num]; const int type = iaparams.type; - if ( type == BONDED_IA_IBM_VOLUME_CONSERVATION ) - { - if ( !p1.p.is_virtual) { printf("Error. Encountered non-virtual particle with VOLUME_CONSERVATION_IBM\n"); exit(1); } + if (type == BONDED_IA_IBM_VOLUME_CONSERVATION) { + if (!p1.p.is_virtual) { + printf("Error. Encountered non-virtual particle with " + "VOLUME_CONSERVATION_IBM\n"); + exit(1); + } softID = iaparams.p.ibmVolConsParameters.softID; volRef = iaparams.p.ibmVolConsParameters.volRef; kappaV = iaparams.p.ibmVolConsParameters.kappaV; } - // Iterate, increase by the number of partners of this bond + 1 for bond type - j += iaparams.num+1; + // Iterate, increase by the number of partners of this bond + 1 for bond + // type + j += iaparams.num + 1; } - - + // Second round for triel - if ( softID > -1 ) - { + if (softID > -1) { j = 0; - while ( j < p1.bl.n) - { + while (j < p1.bl.n) { const int type_num = p1.bl.e[j]; const Bonded_ia_parameters &iaparams = bonded_ia_params[type_num]; const int type = iaparams.type; - - if ( type == BONDED_IA_IBM_TRIEL ) - { + + if (type == BONDED_IA_IBM_TRIEL) { // Our particle is the leading particle of a triel // Get second and third particle of the triangle - Particle *p2 = local_particles[p1.bl.e[j+1]]; - Particle *p3 = local_particles[p1.bl.e[j+2]]; - + Particle *p2 = local_particles[p1.bl.e[j + 1]]; + Particle *p3 = local_particles[p1.bl.e[j + 2]]; + // Unfold position of first node - // this is to get a continuous trajectory with no jumps when box boundaries are crossed - double x1[3] = { p1.r.p[0], p1.r.p[1], p1.r.p[2] }; - int img[3] = { p1.l.i[0], p1.l.i[1], p1.l.i[2] }; - unfold_position(x1,img); - + // this is to get a continuous trajectory with no jumps when box + // boundaries are crossed + double x1[3] = {p1.r.p[0], p1.r.p[1], p1.r.p[2]}; + int img[3] = {p1.l.i[0], p1.l.i[1], p1.l.i[2]}; + unfold_position(x1, img); + // Unfolding seems to work only for the first particle of a triel // so get the others from relative vectors considering PBC double a12[3]; get_mi_vector(a12, p2->r.p, x1); double a13[3]; get_mi_vector(a13, p3->r.p, x1); - - // Now we have the true and good coordinates // Compute force according to eq. C.46 Krüger thesis // It is the same as deriving Achim's equation w.r.t x - /* const double fact = kappaV * 1/6. * (IBMVolumesCurrent[softID] - volRef) / IBMVolumesCurrent[softID]; - + /* const double fact = kappaV * 1/6. * + (IBMVolumesCurrent[softID] - volRef) / IBMVolumesCurrent[softID]; + double x2[3]; double x3[3]; - + for (int i=0; i < 3; i++) { x2[i] = x1[i] + a12[i]; x3[i] = x1[i] + a13[i]; } - + double n[3]; vector_product(x3, x2, n); for (int k=0; k < 3; k++) p1.f.f[k] += fact*n[k]; @@ -343,40 +352,39 @@ void ImmersedBoundaries::calc_volume_force() for (int k=0; k < 3; k++) p2->f.f[k] += fact*n[k]; vector_product(x2, x1, n); for (int k=0; k < 3; k++) p3->f.f[k] += fact*n[k];*/ - - - // This is Dupin 2008. I guess the result will be very similar as the code above + + // This is Dupin 2008. I guess the result will be very similar as + // the code above double n[3]; vector_product(a12, a13, n); - const double ln = sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] ); + const double ln = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); const double A = 0.5 * ln; - const double fact = kappaV * (VolumesCurrent[softID] - volRef) / VolumesCurrent[softID]; + const double fact = kappaV * (VolumesCurrent[softID] - volRef) / + VolumesCurrent[softID]; double nHat[3]; nHat[0] = n[0] / ln; nHat[1] = n[1] / ln; nHat[2] = n[2] / ln; - + double force[3]; force[0] = -fact * A * nHat[0]; force[1] = -fact * A * nHat[1]; force[2] = -fact * A * nHat[2]; - + // Add forces - for (int k=0; k < 3; k++) - { + for (int k = 0; k < 3; k++) { p1.f.f[k] += force[k]; p2->f.f[k] += force[k]; p3->f.f[k] += force[k]; } - } - // Iterate, increase by the number of partners of this bond + 1 for bond type - j += iaparams.num+1; + // Iterate, increase by the number of partners of this bond + 1 for + // bond type + j += iaparams.num + 1; } } } } } - #endif diff --git a/src/core/immersed_boundary/ImmersedBoundaries.hpp b/src/core/immersed_boundary/ImmersedBoundaries.hpp index febd2da49b..67ab260719 100644 --- a/src/core/immersed_boundary/ImmersedBoundaries.hpp +++ b/src/core/immersed_boundary/ImmersedBoundaries.hpp @@ -1,33 +1,29 @@ #ifndef IMMERSED_BOUNDARY_IMMERSED_BOUNDARIES_HPP #define IMMERSED_BOUNDARY_IMMERSED_BOUNDARIES_HPP -#include "config.hpp" +#include "config.hpp" #include - - - #ifdef IMMERSED_BOUNDARY class ImmersedBoundaries { - public: - ImmersedBoundaries() : - MaxNumIBM(1000), - VolumeInitDone(false) - { - VolumesCurrent.resize(MaxNumIBM); - } - void init_volume_conservation(); - void volume_conservation(); - int volume_conservation_reset_params(const int bond_type, const double volRef); - int volume_conservation_set_params(const int bond_type, const int softID, const double kappaV); - void calc_volumes(); - void calc_volume_force(); - private: - const int MaxNumIBM; - std::vector VolumesCurrent; - bool VolumeInitDone = false; +public: + ImmersedBoundaries() : MaxNumIBM(1000), VolumeInitDone(false) { + VolumesCurrent.resize(MaxNumIBM); + } + void init_volume_conservation(); + void volume_conservation(); + int volume_conservation_reset_params(const int bond_type, + const double volRef); + int volume_conservation_set_params(const int bond_type, const int softID, + const double kappaV); + void calc_volumes(); + void calc_volume_force(); + +private: + const int MaxNumIBM; + std::vector VolumesCurrent; + bool VolumeInitDone = false; }; #endif #endif - diff --git a/src/core/immersed_boundary/ibm_tribend.hpp b/src/core/immersed_boundary/ibm_tribend.hpp index fe99a3c547..48c18c4c16 100644 --- a/src/core/immersed_boundary/ibm_tribend.hpp +++ b/src/core/immersed_boundary/ibm_tribend.hpp @@ -9,7 +9,9 @@ extern double maxBendingForce, maxBendingDist, maxX; // This function is used to set the parameters // Also calculates and stores the reference state -int IBM_Tribend_SetParams(const int bond_type, const int ind1, const int ind2, const int ind3, const int ind4, const double kb, const bool flat); +int IBM_Tribend_SetParams(const int bond_type, const int ind1, const int ind2, + const int ind3, const int ind4, const double kb, + const bool flat); // For reading checkpoints. // Idea: * parameters are set in the run-continue script // * also reference shape is recomputed there @@ -17,7 +19,9 @@ int IBM_Tribend_SetParams(const int bond_type, const int ind1, const int ind2, c int IBM_Tribend_ResetParams(const int bond_type, const double kb); // This function calculates and adds the actual force -void IBM_Tribend_CalcForce(Particle *p1, const int numPartners, Particle **const partners, const Bonded_ia_parameters &iaparams); +void IBM_Tribend_CalcForce(Particle *p1, const int numPartners, + Particle **const partners, + const Bonded_ia_parameters &iaparams); #endif diff --git a/src/core/immersed_boundary/ibm_triel.hpp b/src/core/immersed_boundary/ibm_triel.hpp index 35d85da9f8..7398a8442c 100644 --- a/src/core/immersed_boundary/ibm_triel.hpp +++ b/src/core/immersed_boundary/ibm_triel.hpp @@ -6,15 +6,20 @@ // This function is used to set the parameters // Also calculates and stores the reference state -int IBM_Triel_SetParams(const int bond_type, const int ind1, const int ind2, const int ind3, const double maxDist, const tElasticLaw elasticLaw, const double k1, const double k2); +int IBM_Triel_SetParams(const int bond_type, const int ind1, const int ind2, + const int ind3, const double maxDist, + const tElasticLaw elasticLaw, const double k1, + const double k2); // For reading checkpoints. // Idea: * parameters are set in the run-continue script // * also reference shape is recomputed there // * only pass two values here to check consistency -int IBM_Triel_ResetParams(const int bond_type, const double k1, const double l0); +int IBM_Triel_ResetParams(const int bond_type, const double k1, + const double l0); // This function calculates and adds the actual force -int IBM_Triel_CalcForce(Particle *p1,Particle *p2, Particle *p3, Bonded_ia_parameters *iaparams); +int IBM_Triel_CalcForce(Particle *p1, Particle *p2, Particle *p3, + Bonded_ia_parameters *iaparams); #endif diff --git a/src/core/initialize.cpp b/src/core/initialize.cpp index e29b130a38..2069108a19 100755 --- a/src/core/initialize.cpp +++ b/src/core/initialize.cpp @@ -155,9 +155,9 @@ void on_integration_start() { } #endif - /********************************************/ - /* end sanity checks */ - /********************************************/ +/********************************************/ +/* end sanity checks */ +/********************************************/ #ifdef LB_GPU if (lattice_switch & LATTICE_LB_GPU && this_node == 0) { @@ -385,7 +385,6 @@ void on_constraint_change() { void on_lbboundary_change() { EVENT_TRACE(fprintf(stderr, "%d: on_lbboundary_change\n", this_node)); invalidate_obs(); - #ifdef LB_BOUNDARIES if (lattice_switch & LATTICE_LB) { diff --git a/src/core/initialize.hpp b/src/core/initialize.hpp index af517706f3..b0c2f242cd 100755 --- a/src/core/initialize.hpp +++ b/src/core/initialize.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef INITIALZE_H #define INITIALZE_H diff --git a/src/core/integrate.cpp b/src/core/integrate.cpp index 682e53b55f..1c8de3e4e3 100644 --- a/src/core/integrate.cpp +++ b/src/core/integrate.cpp @@ -55,10 +55,10 @@ #include "utils.hpp" #include "virtual_sites.hpp" -#include "immersed_boundaries.hpp" -#include "npt.hpp" #include "collision.hpp" #include "forces.hpp" +#include "immersed_boundaries.hpp" +#include "npt.hpp" #include #include @@ -112,7 +112,7 @@ void propagate_pos(); \f[ v(t+0.5 \Delta t) = v(t) + 0.5 \Delta t f(t)/m \f]
\f[ p(t+\Delta t) = p(t) + \Delta t v(t+0.5 \Delta t) \f] */ void propagate_vel_pos(); -/** Integration step 4 of the Velocity Verletintegrator and finalize +/** Integration step 4 of the Velocity Verletintegrator and finalize instantanious pressure calculation:
\f[ v(t+\Delta t) = v(t+0.5 \Delta t) + 0.5 \Delta t f(t+\Delta t)/m \f] */ void propagate_vel_finalize_p_inst(); @@ -217,7 +217,6 @@ void integrate_vv(int n_steps, int reuse_forces) { immersed_boundaries.init_volume_conservation(); #endif - /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; @@ -258,15 +257,15 @@ void integrate_vv(int n_steps, int reuse_forces) { "sampling.\n"); #endif - // Communication step: distribute ghost positions - cells_update_ghosts(); + // Communication step: distribute ghost positions + cells_update_ghosts(); // VIRTUAL_SITES pos (and vel for DPD) update for security reason !!! #ifdef VIRTUAL_SITES - virtual_sites()->update(); - if (virtual_sites()->need_ghost_comm_after_pos_update()) { - ghost_communicator(&cell_structure.update_ghost_pos_comm); - } + virtual_sites()->update(); + if (virtual_sites()->need_ghost_comm_after_pos_update()) { + ghost_communicator(&cell_structure.update_ghost_pos_comm); + } #endif force_calc(); @@ -363,15 +362,15 @@ void integrate_vv(int n_steps, int reuse_forces) { transfer_momentum_gpu = (n_part > 0); #endif - // Communication step: distribute ghost positions - cells_update_ghosts(); + // Communication step: distribute ghost positions + cells_update_ghosts(); // VIRTUAL_SITES pos (and vel for DPD) update for security reason !!! #ifdef VIRTUAL_SITES - virtual_sites()->update(); - if (virtual_sites()->need_ghost_comm_after_pos_update()) { - ghost_communicator(&cell_structure.update_ghost_pos_comm); - } + virtual_sites()->update(); + if (virtual_sites()->need_ghost_comm_after_pos_update()) { + ghost_communicator(&cell_structure.update_ghost_pos_comm); + } #endif force_calc(); @@ -462,10 +461,10 @@ void integrate_vv(int n_steps, int reuse_forces) { } // VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES - if (virtual_sites()->need_ghost_comm_before_vel_update()) { - ghost_communicator(&cell_structure.update_ghost_pos_comm); - } - virtual_sites()->update(false); // Recalc positions = false + if (virtual_sites()->need_ghost_comm_before_vel_update()) { + ghost_communicator(&cell_structure.update_ghost_pos_comm); + } + virtual_sites()->update(false); // Recalc positions = false #endif #ifdef VALGRIND_INSTRUMENTATION @@ -535,8 +534,9 @@ void propagate_vel_finalize_p_inst() { #ifdef NPT if (integ_switch == INTEG_METHOD_NPT_ISO && (nptiso.geometry & nptiso.nptgeom_dir[j])) { - nptiso.p_vel[j] += Utils::sqr(p.m.v[j] * time_step) * p.p.mass; - p.m.v[j] += 0.5 * time_step / p.p.mass * p.f.f[j] + friction_therm0_nptiso(p.m.v[j]) / p.p.mass; + nptiso.p_vel[j] += Utils::sqr(p.m.v[j] * time_step) * p.p.mass; + p.m.v[j] += 0.5 * time_step / p.p.mass * p.f.f[j] + + friction_therm0_nptiso(p.m.v[j]) / p.p.mass; } else #endif /* Propagate velocity: v(t+dt) = v(t+0.5*dt) + 0.5*dt * a(t+dt) */ @@ -696,8 +696,9 @@ void propagate_vel() { #ifdef NPT if (integ_switch == INTEG_METHOD_NPT_ISO && (nptiso.geometry & nptiso.nptgeom_dir[j])) { - p.m.v[j] += p.f.f[j] * 0.5 * time_step / p.p.mass + friction_therm0_nptiso(p.m.v[j]) / p.p.mass; - nptiso.p_vel[j] += Utils::sqr(p.m.v[j] * time_step) * p.p.mass; + p.m.v[j] += p.f.f[j] * 0.5 * time_step / p.p.mass + + friction_therm0_nptiso(p.m.v[j]) / p.p.mass; + nptiso.p_vel[j] += Utils::sqr(p.m.v[j] * time_step) * p.p.mass; } else #endif /* Propagate velocities: v(t+0.5*dt) = v(t) + 0.5*dt * a(t) */ diff --git a/src/core/integrate.hpp b/src/core/integrate.hpp index a9bd02056e..4928368247 100755 --- a/src/core/integrate.hpp +++ b/src/core/integrate.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef INTEGRATE_H #define INTEGRATE_H @@ -26,8 +26,8 @@ * For more information see \ref integrate.cpp "integrate.c". */ -#define INTEG_METHOD_NPT_ISO 0 -#define INTEG_METHOD_NVT 1 +#define INTEG_METHOD_NPT_ISO 0 +#define INTEG_METHOD_NVT 1 #define INTEG_METHOD_STEEPEST_DESCENT 2 /************************************************************/ @@ -59,7 +59,7 @@ extern double skin; extern bool skin_set; /** If non-zero, the forces will be recalculated before the next integration. */ -extern int recalc_forces; +extern int recalc_forces; /** Average number of integration steps the verlet list has been re used. */ extern double verlet_reuse; @@ -88,14 +88,14 @@ void integrate_vv(int n_steps, int reuse_forces); /** function that rescales all velocities on one node according to a new time step. */ -void rescale_velocities(double scale); +void rescale_velocities(double scale); /*@}*/ int python_integrate(int n_steps, bool recalc_forces, bool reuse_forces); void integrate_set_nvt(); -int integrate_set_npt_isotropic(double ext_pressure, double piston, int xdir, int ydir, int zdir, bool cubic_box); - +int integrate_set_npt_isotropic(double ext_pressure, double piston, int xdir, + int ydir, int zdir, bool cubic_box); #endif diff --git a/src/core/interaction_data.cpp b/src/core/interaction_data.cpp index 1a60ba6768..ad72ac6dc7 100755 --- a/src/core/interaction_data.cpp +++ b/src/core/interaction_data.cpp @@ -23,13 +23,13 @@ */ #include "interaction_data.hpp" #include "actor/DipolarDirectSum.hpp" +#include "actor/DipolarDirectSum.hpp" #include "buckingham.hpp" #include "cells.hpp" #include "communication.hpp" #include "cos2.hpp" #include "debye_hueckel.hpp" #include "dpd.hpp" -#include "thermalized_bond.hpp" #include "elc.hpp" #include "errorhandling.hpp" #include "gaussian.hpp" @@ -38,6 +38,8 @@ #include "hat.hpp" #include "hertzian.hpp" #include "initialize.hpp" +#include "initialize.hpp" +#include "interaction_data.hpp" #include "interaction_data.hpp" #include "lj.hpp" #include "ljcos.hpp" @@ -46,9 +48,7 @@ #include "maggs.hpp" #include "magnetic_non_p3m_methods.hpp" #include "mdlc_correction.hpp" -#include "initialize.hpp" -#include "interaction_data.hpp" -#include "actor/DipolarDirectSum.hpp" +#include "thermalized_bond.hpp" #ifdef DIPOLAR_BARNES_HUT #include "actor/DipolarBarnesHut.hpp" #endif @@ -70,15 +70,14 @@ #include "umbrella.hpp" #include "utils.hpp" #include "utils/serialization/IA_parameters.hpp" -#include -#include #include #include -#include -#include #include #include - +#include +#include +#include +#include /**************************************** * variables @@ -89,10 +88,10 @@ std::vector ia_params; #if defined(ELECTROSTATICS) || defined(DIPOLES) Coulomb_parameters coulomb = { #ifdef ELECTROSTATICS - 0.0, COULOMB_NONE, + 0.0, COULOMB_NONE, #endif #ifdef DIPOLES - 0.0, DIPOLAR_NONE, + 0.0, DIPOLAR_NONE, #endif }; #endif @@ -186,9 +185,9 @@ static void recalc_maximal_cutoff_bonded() { max_cut_bonded = bonded_ia_params[i].p.harmonic.r_cut; break; case BONDED_IA_THERMALIZED_DIST: - if ((bonded_ia_params[i].p.thermalized_bond.r_cut > 0) && - (max_cut_bonded < bonded_ia_params[i].p.thermalized_bond.r_cut)) - max_cut_bonded = bonded_ia_params[i].p.thermalized_bond.r_cut; + if ((bonded_ia_params[i].p.thermalized_bond.r_cut > 0) && + (max_cut_bonded < bonded_ia_params[i].p.thermalized_bond.r_cut)) + max_cut_bonded = bonded_ia_params[i].p.thermalized_bond.r_cut; break; case BONDED_IA_RIGID_BOND: if (max_cut_bonded < sqrt(bonded_ia_params[i].p.rigid_bond.d2)) @@ -503,7 +502,6 @@ void make_particle_type_exist_local(int type) { realloc_ia_params(type + 1); } - void make_bond_type_exist(int type) { int i, ns = type + 1; const auto old_size = bonded_ia_params.size(); @@ -580,10 +578,9 @@ void set_dipolar_method_local(DipolarInteraction method) { } #endif #ifdef DIPOLAR_BARNES_HUT -if ((coulomb.Dmethod == DIPOLAR_BH_GPU) && (method != DIPOLAR_BH_GPU)) -{ - deactivate_dipolar_barnes_hut(); -} + if ((coulomb.Dmethod == DIPOLAR_BH_GPU) && (method != DIPOLAR_BH_GPU)) { + deactivate_dipolar_barnes_hut(); + } #endif // BARNES_HUT coulomb.Dmethod = method; } @@ -595,71 +592,63 @@ if ((coulomb.Dmethod == DIPOLAR_BH_GPU) && (method != DIPOLAR_BH_GPU)) /* electrostatics */ /********************************************************************************/ -int coulomb_set_prefactor(double prefactor) -{ +int coulomb_set_prefactor(double prefactor) { if (prefactor < 0.0) { runtimeErrorMsg() << "Coulomb prefactor has to be >=0"; return ES_ERROR; } - - coulomb.prefactor=prefactor; + + coulomb.prefactor = prefactor; mpi_bcast_coulomb_params(); - return ES_OK; } -/** @brief Deactivates the current Coulomb mhthod +/** @brief Deactivates the current Coulomb mhthod This was part of coulomb_set_bjerrum() */ void deactivate_coulomb_method() { -coulomb.prefactor =0; -switch (coulomb.method) { + coulomb.prefactor = 0; + switch (coulomb.method) { #ifdef P3M - case COULOMB_ELC_P3M: - case COULOMB_P3M_GPU: - case COULOMB_P3M: - break; + case COULOMB_ELC_P3M: + case COULOMB_P3M_GPU: + case COULOMB_P3M: + break; #endif - case COULOMB_DH: - dh_params.r_cut = 0.0; - dh_params.kappa = 0.0; - case COULOMB_RF: - case COULOMB_INTER_RF: - rf_params.kappa = 0.0; - rf_params.epsilon1 = 0.0; - rf_params.epsilon2 = 0.0; - rf_params.r_cut = 0.0; - rf_params.B = 0.0; - case COULOMB_MMM1D: - mmm1d_params.maxPWerror = 1e40; - default: - break; - } + case COULOMB_DH: + dh_params.r_cut = 0.0; + dh_params.kappa = 0.0; + case COULOMB_RF: + case COULOMB_INTER_RF: + rf_params.kappa = 0.0; + rf_params.epsilon1 = 0.0; + rf_params.epsilon2 = 0.0; + rf_params.r_cut = 0.0; + rf_params.B = 0.0; + case COULOMB_MMM1D: + mmm1d_params.maxPWerror = 1e40; + default: + break; + } - mpi_bcast_coulomb_params(); - coulomb.method = COULOMB_NONE; - mpi_bcast_coulomb_params(); + mpi_bcast_coulomb_params(); + coulomb.method = COULOMB_NONE; + mpi_bcast_coulomb_params(); } - - - - - /* ========================================================= ========================================================= */ #endif /*ifdef ELECTROSTATICS */ #ifdef DIPOLES -int dipolar_set_Dprefactor(double prefactor) -{ - if (prefactor < 0.0){ +int dipolar_set_Dprefactor(double prefactor) { + if (prefactor < 0.0) { runtimeErrorMsg() << "Dipolar prefactor has to be >=0"; return ES_ERROR; } - + coulomb.Dprefactor = prefactor; mpi_bcast_coulomb_params(); @@ -668,7 +657,6 @@ int dipolar_set_Dprefactor(double prefactor) #endif /* ifdef DIPOLES */ - int virtual_set_params(int bond_type) { if (bond_type < 0) return ES_ERROR; diff --git a/src/core/interaction_data.hpp b/src/core/interaction_data.hpp index 315ccd84f3..2d8f5789a5 100755 --- a/src/core/interaction_data.hpp +++ b/src/core/interaction_data.hpp @@ -188,7 +188,7 @@ struct IA_parameters { double LJ_shift = 0.0; double LJ_offset = 0.0; double LJ_min = 0.0; - /*@}*/ +/*@}*/ #endif @@ -440,7 +440,6 @@ struct Coulomb_parameters { double Dprefactor; DipolarInteraction Dmethod; #endif - }; #ifdef ELECTROSTATICS @@ -477,15 +476,15 @@ struct Oif_global_forces_bond_parameters { /** Parameters for oif_local_forces */ struct Oif_local_forces_bond_parameters { - double r0; - double ks; - double kslin; - double phi0; - double kb; - double A01; - double A02; - double kal; - double kvisc; + double r0; + double ks; + double kslin; + double phi0; + double kb; + double A01; + double A02; + double kal; + double kvisc; }; /** Parameters for harmonic bond Potential */ @@ -497,15 +496,15 @@ struct Harmonic_bond_parameters { /** Parameters for Thermalized bond **/ struct Thermalized_bond_parameters { - double temp_com; - double gamma_com; - double temp_distance; - double gamma_distance; - double r_cut; - double pref1_com; - double pref2_com; - double pref1_dist; - double pref2_dist; + double temp_com; + double gamma_com; + double temp_distance; + double gamma_distance; + double r_cut; + double pref1_com; + double pref2_com; + double pref1_dist; + double pref2_dist; }; #ifdef ROTATION @@ -526,11 +525,15 @@ struct Quartic_bond_parameters { }; /** Parameters for coulomb bond Potential */ -struct Bonded_coulomb_bond_parameters { double prefactor; }; +struct Bonded_coulomb_bond_parameters { + double prefactor; +}; #ifdef P3M /** Parameters for coulomb bond p3m shortrange Potential */ -struct Bonded_coulomb_p3m_sr_bond_parameters { double q1q2; }; +struct Bonded_coulomb_p3m_sr_bond_parameters { + double q1q2; +}; #endif /** Parameters for three body angular potential (bond-angle potentials). @@ -545,7 +548,6 @@ struct Angle_bond_parameters { double phi0; double cos_phi0; double sin_phi0; - }; /** Parameters for three body angular potential (bond_angle_harmonic). @@ -598,8 +600,7 @@ struct Umbrella_bond_parameters { #endif /** Dummy parameters for -LJ Potential */ -struct Subt_lj_bond_parameters { -}; +struct Subt_lj_bond_parameters {}; /**Parameters for the rigid_bond/SHAKE/RATTLE ALGORITHM*/ struct Rigid_bond_parameters { @@ -656,7 +657,6 @@ struct IBM_Triel_Parameters { tElasticLaw elasticLaw; double k1; double k2; - }; /** Parameters for IBM volume conservation bond **/ @@ -679,7 +679,6 @@ struct IBM_Tribend_Parameters { // Reference angle double theta0; - }; /** Union in which to store the parameters of an individual bonded interaction diff --git a/src/core/io/mpiio/mpiio.cpp b/src/core/io/mpiio/mpiio.cpp index f07c01ba6e..317dfda21f 100644 --- a/src/core/io/mpiio/mpiio.cpp +++ b/src/core/io/mpiio/mpiio.cpp @@ -51,13 +51,13 @@ #include "config.hpp" #include "cells.hpp" +#include "errorhandling.hpp" #include "initialize.hpp" #include "integrate.hpp" #include "interaction_data.hpp" #include "mpiio.hpp" #include "particle_data.hpp" #include "utils.hpp" -#include "errorhandling.hpp" #include @@ -80,8 +80,8 @@ namespace Mpiio { * \param MPI_T The MPI_Datatype corresponding to the template parameter T. */ template -static void mpiio_dump_array(const std::string & fn, T *arr, size_t len, size_t pref, - MPI_Datatype MPI_T) { +static void mpiio_dump_array(const std::string &fn, T *arr, size_t len, + size_t pref, MPI_Datatype MPI_T) { MPI_File f; int ret; @@ -115,7 +115,7 @@ static void mpiio_dump_array(const std::string & fn, T *arr, size_t len, size_t * \param fn The filename to write to * \param fields The dumped fields */ -static void dump_info(const std::string & fn, unsigned fields) { +static void dump_info(const std::string &fn, unsigned fields) { static std::vector npartners; int success; FILE *f = fopen(fn.c_str(), "wb"); @@ -138,8 +138,9 @@ static void dump_info(const std::string & fn, unsigned fields) { } auto ia_params_size = static_cast(bonded_ia_params.size()); success = success && (fwrite(&ia_params_size, sizeof(size_t), 1, f) == 1); - success = success && (fwrite(npartners.data(), sizeof(int), bonded_ia_params.size(), f) == - bonded_ia_params.size()); + success = + success && (fwrite(npartners.data(), sizeof(int), bonded_ia_params.size(), + f) == bonded_ia_params.size()); fclose(f); if (!success) { fprintf(stderr, "MPI-IO Error: Failed to write %s.\n", fn.c_str()); @@ -246,7 +247,7 @@ void mpi_mpiio_common_write(const char *filename, unsigned fields) { * \param elem_sz Sizeof a single element * \return The number of elements stored binary in the file */ -static int get_num_elem(const std::string & fn, size_t elem_sz) { +static int get_num_elem(const std::string &fn, size_t elem_sz) { // Could also be done via MPI_File_open, MPI_File_get_size, // MPI_File_cose. struct stat st; @@ -264,8 +265,8 @@ static int get_num_elem(const std::string & fn, size_t elem_sz) { * have to match! */ template -static void mpiio_read_array(const std::string & fn, T *arr, size_t len, size_t pref, - MPI_Datatype MPI_T) { +static void mpiio_read_array(const std::string &fn, T *arr, size_t len, + size_t pref, MPI_Datatype MPI_T) { MPI_File f; int ret; @@ -299,7 +300,7 @@ static void mpiio_read_array(const std::string & fn, T *arr, size_t len, size_t * \param rank The rank of the current process in MPI_COMM_WORLD * \param file Pointer to store the fields to */ -static void read_head(const std::string & fn, int rank, unsigned *fields) { +static void read_head(const std::string &fn, int rank, unsigned *fields) { FILE *f = nullptr; if (rank == 0) { if (!(f = fopen(fn.c_str(), "rb"))) { @@ -327,8 +328,8 @@ static void read_head(const std::string & fn, int rank, unsigned *fields) { * \param prefs Pointer to store the prefix to * \param nlocalpart Pointer to store the amount of local particles to */ -static void read_prefs(const std::string & fn, int rank, int size, int nglobalpart, - int *pref, int *nlocalpart) { +static void read_prefs(const std::string &fn, int rank, int size, + int nglobalpart, int *pref, int *nlocalpart) { mpiio_read_array(fn, pref, 1, rank, MPI_INT); if (rank > 0) MPI_Send(pref, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD); @@ -376,8 +377,8 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { read_prefs(fnam + ".pref", rank, size, nglobalpart, &pref, &nlocalpart); // Prepare ESPResSo data structures - local_particles = Utils::realloc( - local_particles, sizeof(Particle *) * nglobalpart); + local_particles = + Utils::realloc(local_particles, sizeof(Particle *) * nglobalpart); for (int i = 0; i < nglobalpart; ++i) local_particles[i] = nullptr; n_part = nglobalpart; @@ -456,5 +457,4 @@ void mpi_mpiio_common_read(const char *filename, unsigned fields) { // Out of box particles might be accepted by the cell system. set_resort_particles(Cells::RESORT_GLOBAL); } - } diff --git a/src/core/io/mpiio/mpiio.hpp b/src/core/io/mpiio/mpiio.hpp index 140bcfae4d..491ed28850 100644 --- a/src/core/io/mpiio/mpiio.hpp +++ b/src/core/io/mpiio/mpiio.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file mpiio.hpp * Implements binary output unsing MPI-IO. @@ -53,7 +53,6 @@ void mpi_mpiio_common_write(const char *filename, unsigned fields); * \param fields Specifier which fields to read. */ void mpi_mpiio_common_read(const char *filename, unsigned fields); - } #endif diff --git a/src/core/io/writer/h5md/h5md_core.cpp b/src/core/io/writer/h5md/h5md_core.cpp index 91ddb2462b..2313e54cc9 100644 --- a/src/core/io/writer/h5md/h5md_core.cpp +++ b/src/core/io/writer/h5md/h5md_core.cpp @@ -19,9 +19,9 @@ along with this program. If not, see . */ -#include #include "h5md_core.hpp" #include "core/interaction_data.hpp" +#include namespace Writer { namespace H5md { @@ -206,12 +206,14 @@ void File::create_datasets(bool only_load) { auto chunk_dims = create_chunk_dims(descr.dim, chunk_size, 1); auto maxdims = create_maxdims(descr.dim); auto storage = h5xx::policy::storage::chunked(chunk_dims); - if(descr.type.get_type_id()==H5T_NATIVE_INT) + if (descr.type.get_type_id() == H5T_NATIVE_INT) storage.set(h5xx::policy::storage::fill_value(static_cast(-10))); - else if(descr.type.get_type_id()==H5T_NATIVE_DOUBLE) - storage.set(h5xx::policy::storage::fill_value(static_cast(-10))); + else if (descr.type.get_type_id() == H5T_NATIVE_DOUBLE) + storage.set( + h5xx::policy::storage::fill_value(static_cast(-10))); else - throw std::runtime_error("H5MD writing dataset of this type is not implemented\n"); + throw std::runtime_error( + "H5MD writing dataset of this type is not implemented\n"); auto dataspace = h5xx::dataspace(dims, maxdims); hid_t lcpl_id = H5Pcreate(H5P_LINK_CREATE); H5Pset_create_intermediate_group(lcpl_id, 1); @@ -301,8 +303,8 @@ void File::create_new_file(const std::string &filename) { h5xx::write_attribute(group, "dimension", 3); h5xx::write_attribute(group, "boundary", "periodic"); std::string path_edges = "particles/atoms/box/edges"; - std::vector change_extent_box = - {3}; // for three entries for cuboid box box_l_x, box_l_y, box_l_z + std::vector change_extent_box = { + 3}; // for three entries for cuboid box box_l_x, box_l_y, box_l_z ExtendDataset(path_edges, change_extent_box); h5xx::write_dataset(datasets[path_edges], boxvec); } @@ -339,7 +341,7 @@ void File::fill_arrays_for_h5md_write_with_particle_property( /* store folded particle positions. */ if (write_pos) { Vector3d p = current_particle.r.p; - Vector<3, int> i= current_particle.l.i; + Vector<3, int> i = current_particle.l.i; fold_position(p, i); pos[0][particle_index][0] = p[0]; @@ -426,8 +428,8 @@ void File::Write(int write_dat, PartCfg &partCfg) { int particle_index = 0; for (auto const ¤t_particle : partCfg) { fill_arrays_for_h5md_write_with_particle_property( - particle_index++, id, typ, mass, pos, image, vel, f, - charge, current_particle, write_dat, bond); + particle_index++, id, typ, mass, pos, image, vel, f, charge, + current_particle, write_dat, bond); } } } else { @@ -535,7 +537,8 @@ void File::Write(int write_dat, PartCfg &partCfg) { } } -void File::ExtendDataset(const std::string & path, const std::vector & change_extent) { +void File::ExtendDataset(const std::string &path, + const std::vector &change_extent) { /* Until now the h5xx does not support dataset extending, so we have to use the lower level hdf5 library functions. */ auto &dataset = datasets[path]; @@ -554,8 +557,9 @@ void File::ExtendDataset(const std::string & path, const std::vector & chan /* data is assumed to be three dimensional */ template -void File::WriteDataset(T &data, const std::string &path, const std::vector & change_extent, - hsize_t *offset, hsize_t *count) { +void File::WriteDataset(T &data, const std::string &path, + const std::vector &change_extent, hsize_t *offset, + hsize_t *count) { #ifdef H5MD_DEBUG /* Turn on hdf5 error messages */ H5Eset_auto(H5E_DEFAULT, (H5E_auto_t)H5Eprint, stderr); diff --git a/src/core/io/writer/h5md/h5md_core.hpp b/src/core/io/writer/h5md/h5md_core.hpp index ca378bc8d1..adc6e94aed 100644 --- a/src/core/io/writer/h5md/h5md_core.hpp +++ b/src/core/io/writer/h5md/h5md_core.hpp @@ -22,21 +22,21 @@ #ifndef ESPRESSO_H5MD_CORE_HPP #define ESPRESSO_H5MD_CORE_HPP -#include "cells.hpp" -#include "global.hpp" #include "MpiCallbacks.hpp" #include "PartCfg.hpp" -#include +#include "cells.hpp" +#include "global.hpp" +#include #include +#include +#include #include -#include #include -#include #define BOOST_NO_CXX11_SCOPED_ENUMS #include #undef BOOST_NO_CXX11_SCOPED_ENUMS -#include #include "communication.hpp" +#include extern double sim_time; extern double time_step; @@ -120,13 +120,15 @@ class File { * positions to the dataset. */ template - void WriteDataset(T &data, const std::string &path, const std::vector & change_extent, - hsize_t *offset, hsize_t *count); + void WriteDataset(T &data, const std::string &path, + const std::vector &change_extent, hsize_t *offset, + hsize_t *count); /** * @brief Method that extends datasets by the given extent. */ - void ExtendDataset(const std::string & path, const std::vector & change_extent); + void ExtendDataset(const std::string &path, + const std::vector &change_extent); /** * @brief Method that returns chunk dimensions. @@ -142,7 +144,7 @@ class File { int particle_index, int_array_3d &id, int_array_3d &typ, double_array_3d &mass, double_array_3d &pos, int_array_3d &image, double_array_3d &vel, double_array_3d &f, double_array_3d &charge, - Particle const¤t_particle, int write_dat, int_array_3d &bond); + Particle const ¤t_particle, int write_dat, int_array_3d &bond); /* * @brief Method to write the simulation script to the dataset. */ diff --git a/src/core/lattice.cpp b/src/core/lattice.cpp index b88f02105a..082e4d873a 100644 --- a/src/core/lattice.cpp +++ b/src/core/lattice.cpp @@ -1,24 +1,24 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -/** \file lattice.cpp +/** \file lattice.cpp * * Lattice class definition * @@ -29,133 +29,149 @@ #include "debug.hpp" #include "grid.hpp" -int lattice_switch = LATTICE_OFF ; - -int Lattice::init(double *agrid, double* offset, int halo_size, size_t dim) { - /* determine the number of local lattice nodes */ - for (int d=0; d<3; d++) { - this->agrid[d] = agrid[d]; - this->global_grid[d] = (int)dround(box_l[d]/agrid[d]); - this->offset[d]=offset[d]; - this->local_index_offset[d]=(int) ceil((my_left[d]-this->offset[d])/this->agrid[d]); - this->local_offset[d] = this->offset[d] + - this->local_index_offset[d]*this->agrid[d]; - this->grid[d] = (int) ceil ( ( my_right[d] - this->local_offset[d]-ROUND_ERROR_PREC ) - / this->agrid[d]); - } +int lattice_switch = LATTICE_OFF; + +int Lattice::init(double *agrid, double *offset, int halo_size, size_t dim) { + /* determine the number of local lattice nodes */ + for (int d = 0; d < 3; d++) { + this->agrid[d] = agrid[d]; + this->global_grid[d] = (int)dround(box_l[d] / agrid[d]); + this->offset[d] = offset[d]; + this->local_index_offset[d] = + (int)ceil((my_left[d] - this->offset[d]) / this->agrid[d]); + this->local_offset[d] = + this->offset[d] + this->local_index_offset[d] * this->agrid[d]; + this->grid[d] = + (int)ceil((my_right[d] - this->local_offset[d] - ROUND_ERROR_PREC) / + this->agrid[d]); + } - // sanity checks - for (int dir=0;dir<3;dir++) { - // check if local_box_l is compatible with lattice spacing - if (fabs(local_box_l[dir]-this->grid[dir]*agrid[dir]) > ROUND_ERROR_PREC*box_l[dir]) { - runtimeErrorMsg() << "Lattice spacing agrid["<< dir << "]=" << agrid[dir] \ - << " is incompatible with local_box_l["<< dir << "]=" << local_box_l[dir]\ - << " ( box_l["<< dir << "]=" << box_l[dir] \ - << " node_grid["<< dir << "]=" << node_grid[dir] <<" )"; - } + // sanity checks + for (int dir = 0; dir < 3; dir++) { + // check if local_box_l is compatible with lattice spacing + if (fabs(local_box_l[dir] - this->grid[dir] * agrid[dir]) > + ROUND_ERROR_PREC * box_l[dir]) { + runtimeErrorMsg() << "Lattice spacing agrid[" << dir << "]=" << agrid[dir] + << " is incompatible with local_box_l[" << dir + << "]=" << local_box_l[dir] << " ( box_l[" << dir + << "]=" << box_l[dir] << " node_grid[" << dir + << "]=" << node_grid[dir] << " )"; } + } - LATTICE_TRACE(fprintf(stderr,"%d: box_l (%.3f,%.3f,%.3f) grid (%d,%d,%d) node_neighbors (%d,%d,%d,%d,%d,%d)\n",this_node,local_box_l[0],local_box_l[1],local_box_l[2],this->grid[0],this->grid[1],this->grid[2],node_neighbors[0],node_neighbors[1],node_neighbors[2],node_neighbors[3],node_neighbors[4],node_neighbors[5])); - - this->halo_size = halo_size; - /* determine the number of total nodes including halo */ - this->halo_grid[0] = this->grid[0] + 2*halo_size ; - this->halo_grid[1] = this->grid[1] + 2*halo_size ; - this->halo_grid[2] = this->grid[2] + 2*halo_size ; - - this->halo_grid_volume = this->halo_grid[0]*this->halo_grid[1]*this->halo_grid[2] ; - this->halo_offset = get_linear_index(halo_size,halo_size,halo_size,this->halo_grid) ; - - return ES_OK; - + LATTICE_TRACE(fprintf(stderr, "%d: box_l (%.3f,%.3f,%.3f) grid (%d,%d,%d) " + "node_neighbors (%d,%d,%d,%d,%d,%d)\n", + this_node, local_box_l[0], local_box_l[1], + local_box_l[2], this->grid[0], this->grid[1], + this->grid[2], node_neighbors[0], node_neighbors[1], + node_neighbors[2], node_neighbors[3], node_neighbors[4], + node_neighbors[5])); + + this->halo_size = halo_size; + /* determine the number of total nodes including halo */ + this->halo_grid[0] = this->grid[0] + 2 * halo_size; + this->halo_grid[1] = this->grid[1] + 2 * halo_size; + this->halo_grid[2] = this->grid[2] + 2 * halo_size; + + this->halo_grid_volume = + this->halo_grid[0] * this->halo_grid[1] * this->halo_grid[2]; + this->halo_offset = + get_linear_index(halo_size, halo_size, halo_size, this->halo_grid); + + return ES_OK; } -void Lattice::map_position_to_lattice(const Vector3d& pos, index_t node_index[8], double delta[6]) { - int ind[3]; - - /* determine the elementary lattice cell containing the particle - and the relative position of the particle in this cell */ - for (int dir=0;dir<3;dir++) { - double lpos = pos[dir] - my_left[dir]; - double rel = lpos/this->agrid[dir] + 0.5; // +1 for halo offset - ind[dir] = (int)floor(rel); - - /* surrounding elementary cell is not completely inside this box, - adjust if this is due to round off errors */ - if (ind[dir] < 0) { - if (fabs(rel) < ROUND_ERROR_PREC) { - ind[dir] = 0; // TODO - } else { - fprintf(stderr,"%d: map_position_to_lattice: position (%f,%f,%f) not inside a local plaquette in dir %d ind[dir]=%d rel=%f lpos=%f.\n",this_node,pos[0],pos[1],pos[2],dir,ind[dir],rel,lpos); - } - } - else if (ind[dir] > this->grid[dir]) { - if (lpos - local_box_l[dir] < ROUND_ERROR_PREC*local_box_l[dir]) - ind[dir] = this->grid[dir]; - else - fprintf(stderr,"%d: map_position_to_lattice: position (%f,%f,%f) not inside a local plaquette in dir %d ind[dir]=%d rel=%f lpos=%f.\n",this_node,pos[0],pos[1],pos[2],dir,ind[dir],rel,lpos); - } - - delta[3+dir] = rel - ind[dir]; // delta_x/a - delta[dir] = 1.0 - delta[3+dir]; +void Lattice::map_position_to_lattice(const Vector3d &pos, + index_t node_index[8], double delta[6]) { + int ind[3]; + + /* determine the elementary lattice cell containing the particle + and the relative position of the particle in this cell */ + for (int dir = 0; dir < 3; dir++) { + double lpos = pos[dir] - my_left[dir]; + double rel = lpos / this->agrid[dir] + 0.5; // +1 for halo offset + ind[dir] = (int)floor(rel); + + /* surrounding elementary cell is not completely inside this box, + adjust if this is due to round off errors */ + if (ind[dir] < 0) { + if (fabs(rel) < ROUND_ERROR_PREC) { + ind[dir] = 0; // TODO + } else { + fprintf(stderr, "%d: map_position_to_lattice: position (%f,%f,%f) not " + "inside a local plaquette in dir %d ind[dir]=%d rel=%f " + "lpos=%f.\n", + this_node, pos[0], pos[1], pos[2], dir, ind[dir], rel, lpos); + } + } else if (ind[dir] > this->grid[dir]) { + if (lpos - local_box_l[dir] < ROUND_ERROR_PREC * local_box_l[dir]) + ind[dir] = this->grid[dir]; + else + fprintf(stderr, "%d: map_position_to_lattice: position (%f,%f,%f) not " + "inside a local plaquette in dir %d ind[dir]=%d rel=%f " + "lpos=%f.\n", + this_node, pos[0], pos[1], pos[2], dir, ind[dir], rel, lpos); } - node_index[0] = get_linear_index(ind[0],ind[1],ind[2],this->halo_grid); - node_index[1] = node_index[0] + 1; - node_index[2] = node_index[0] + this->halo_grid[0]; - node_index[3] = node_index[0] + this->halo_grid[0] + 1; - node_index[4] = node_index[0] + this->halo_grid[0]*this->halo_grid[1]; - node_index[5] = node_index[4] + 1; - node_index[6] = node_index[4] + this->halo_grid[0]; - node_index[7] = node_index[4] + this->halo_grid[0] + 1; + delta[3 + dir] = rel - ind[dir]; // delta_x/a + delta[dir] = 1.0 - delta[3 + dir]; + } + + node_index[0] = get_linear_index(ind[0], ind[1], ind[2], this->halo_grid); + node_index[1] = node_index[0] + 1; + node_index[2] = node_index[0] + this->halo_grid[0]; + node_index[3] = node_index[0] + this->halo_grid[0] + 1; + node_index[4] = node_index[0] + this->halo_grid[0] * this->halo_grid[1]; + node_index[5] = node_index[4] + 1; + node_index[6] = node_index[4] + this->halo_grid[0]; + node_index[7] = node_index[4] + this->halo_grid[0] + 1; } /********************** static Functions **********************/ -void Lattice::map_position_to_lattice_global (Vector3d& pos, int ind[3], double delta[6], double tmp_agrid) { - //not sure why I don't have access to agrid here so I make a temp var and pass it to this function +void Lattice::map_position_to_lattice_global(Vector3d &pos, int ind[3], + double delta[6], + double tmp_agrid) { + // not sure why I don't have access to agrid here so I make a temp var and + // pass it to this function int i; double rel[3]; - // fold the position onto the local box, note here ind is used as a dummy variable - for (i=0;i<3;i++) { - pos[i] = pos[i]-0.5*tmp_agrid; + // fold the position onto the local box, note here ind is used as a dummy + // variable + for (i = 0; i < 3; i++) { + pos[i] = pos[i] - 0.5 * tmp_agrid; } - fold_position (pos,ind); + fold_position(pos, ind); // convert the position into lower left grid point - for (i=0;i<3;i++) { - rel[i] = (pos[i])/tmp_agrid; + for (i = 0; i < 3; i++) { + rel[i] = (pos[i]) / tmp_agrid; } - // calculate the index of the position - for (i=0;i<3;i++) { - ind[i] = floor(rel[i]); - } - - // calculate the linear interpolation weighting - for (i=0;i<3;i++) { - delta[3+i] = rel[i] - ind[i]; - delta[i] = 1 - delta[3+i]; - } + // calculate the index of the position + for (i = 0; i < 3; i++) { + ind[i] = floor(rel[i]); + } + // calculate the linear interpolation weighting + for (i = 0; i < 3; i++) { + delta[3 + i] = rel[i] - ind[i]; + delta[i] = 1 - delta[3 + i]; + } } +int Lattice::map_lattice_to_node(int *ind, int *grid) const { + /* determine coordinates in node_grid */ + grid[0] = (int)floor(ind[0] * this->agrid[0] * box_l_i[0] * node_grid[0]); + grid[1] = (int)floor(ind[1] * this->agrid[1] * box_l_i[1] * node_grid[1]); + grid[2] = (int)floor(ind[2] * this->agrid[2] * box_l_i[2] * node_grid[2]); -int Lattice::map_lattice_to_node(int *ind, int *grid) const - { - /* determine coordinates in node_grid */ - grid[0] = (int)floor(ind[0]*this->agrid[0]*box_l_i[0]*node_grid[0]); - grid[1] = (int)floor(ind[1]*this->agrid[1]*box_l_i[1]*node_grid[1]); - grid[2] = (int)floor(ind[2]*this->agrid[2]*box_l_i[2]*node_grid[2]); - - /* change from global to local lattice coordinates */ - ind[0] = ind[0] - grid[0]*this->grid[0] + this->halo_size; - ind[1] = ind[1] - grid[1]*this->grid[1] + this->halo_size; - ind[2] = ind[2] - grid[2]*this->grid[2] + this->halo_size; - - /* return linear index into node array */ - return map_array_node(grid); - } - + /* change from global to local lattice coordinates */ + ind[0] = ind[0] - grid[0] * this->grid[0] + this->halo_size; + ind[1] = ind[1] - grid[1] * this->grid[1] + this->halo_size; + ind[2] = ind[2] - grid[2] * this->grid[2] + this->halo_size; + /* return linear index into node array */ + return map_array_node(grid); +} diff --git a/src/core/lattice.hpp b/src/core/lattice.hpp index 80cbc08f14..8bbb9c43f0 100644 --- a/src/core/lattice.hpp +++ b/src/core/lattice.hpp @@ -1,6 +1,6 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group This file is part of ESPResSo. @@ -16,9 +16,9 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -/** \file lattice.hpp +/** \file lattice.hpp * * Lattice class definition * Contains the lattice layout and pointers to the data fields. @@ -38,92 +38,100 @@ */ extern int lattice_switch; -#define LATTICE_LB 1 /** Lattice Boltzmann */ -#define LATTICE_LB_GPU 2 /** Lattice Boltzmann */ +#define LATTICE_LB 1 /** Lattice Boltzmann */ +#define LATTICE_LB_GPU 2 /** Lattice Boltzmann */ #define INTERPOLATION_LINEAR 1 -#define LATTICE_OFF 0 /** Lattice off */ +#define LATTICE_OFF 0 /** Lattice off */ class Lattice { public: using index_t = int; - int grid[3] ;/** number of local lattice sites in each direction (excluding halo) */ - int global_grid[3]; - double agrid[3];/** lattice constant */ - - int halo_grid[3] ;/** number of lattice sites in each direction including halo */ - int halo_size;/** halo size in all directions */ - - double offset[3];/** global offset */ - double local_offset[3]; - int local_index_offset[3]; - - index_t halo_grid_volume;/** total number (volume) of lattice sites (including halo) */ - index_t halo_offset;/** offset for number of halo sites stored in front of the local lattice sites */ - - /** Initialize lattice. - * - * This function initializes the variables describing the lattice - * layout. Important: The lattice data is not allocated here! - * - * \param lattice pointer to the lattice - * \param agrid lattice spacing - */ - int init(double* agrid, double* offset, int halo_size, size_t dim); - - /** Map a spatial position to the surrounding lattice sites. - * - * This function takes a global spatial position and determines the - * surrounding elementary cell of the lattice for this position. - * The distance fraction in each direction is also calculated. - *
Remarks: - *
    - *
  • The spatial position has to be in the local domain.
  • - *
  • The lattice sites of the elementary cell are returned as local indices
  • - *
- * \param lattice pointer to the lattice (Input) - * \param pos spatial position (Input) - * \param node_index local indices of the surrounding lattice sites (Output) - * \param delta distance fraction of pos from the surrounding - * elementary cell, 6 directions (Output) - */ - void map_position_to_lattice(const Vector3d& pos, index_t node_index[8], double delta[6]); - - /********************** Inline Functions **********************/ - - /** Map a global lattice site to the node grid. - * - * This function determines the processor responsible for - * the specified lattice site. The coordinates of the site are - * taken as global coordinates and are returned as local coordinates. - * - * \param lattice pointer to the lattice - * \param ind global coordinates of the lattice site (Input) - * \param grid local coordinates of the lattice site (Output) - * \return index of the node for the lattice site - */ - int map_lattice_to_node(int *ind, int *grid) const; - - /********************** static Functions **********************/ - - /** Map a spatial position to the surrounding lattice sites. - * - * This function takes a global spatial position and determines the - * surrounding elementary cell of the lattice for this position. - * The distance fraction in each direction is also calculated. - *
Remarks: - *
    - *
  • The spatial position is given in global coordinates.
  • - *
  • The lattice sites of the elementary cell are returned as local indices
  • - *
- * \param pos spatial position (Input) - * \param ind global index of the lower left lattice site (Output) - * \param delta distance fraction of pos from the surrounding - * elementary cell, 6 directions (Output) - * \param tmp_agrid lattice mesh distance - */ - static void map_position_to_lattice_global (Vector3d& pos, int ind[3], double delta[6], double tmp_agrid); + int grid[3]; /** number of local lattice sites in each direction (excluding + halo) */ + int global_grid[3]; + double agrid[3]; /** lattice constant */ + + int halo_grid + [3]; /** number of lattice sites in each direction including halo */ + int halo_size; /** halo size in all directions */ + + double offset[3]; /** global offset */ + double local_offset[3]; + int local_index_offset[3]; + + index_t halo_grid_volume; /** total number (volume) of lattice sites + (including halo) */ + index_t halo_offset; /** offset for number of halo sites stored in front of + the local lattice sites */ + + /** Initialize lattice. + * + * This function initializes the variables describing the lattice + * layout. Important: The lattice data is not allocated here! + * + * \param lattice pointer to the lattice + * \param agrid lattice spacing + */ + int init(double *agrid, double *offset, int halo_size, size_t dim); + + /** Map a spatial position to the surrounding lattice sites. + * + * This function takes a global spatial position and determines the + * surrounding elementary cell of the lattice for this position. + * The distance fraction in each direction is also calculated. + *
Remarks: + *
    + *
  • The spatial position has to be in the local domain.
  • + *
  • The lattice sites of the elementary cell are returned as local + * indices
  • + *
+ * \param lattice pointer to the lattice (Input) + * \param pos spatial position (Input) + * \param node_index local indices of the surrounding lattice sites (Output) + * \param delta distance fraction of pos from the surrounding + * elementary cell, 6 directions (Output) + */ + void map_position_to_lattice(const Vector3d &pos, index_t node_index[8], + double delta[6]); + + /********************** Inline Functions **********************/ + + /** Map a global lattice site to the node grid. + * + * This function determines the processor responsible for + * the specified lattice site. The coordinates of the site are + * taken as global coordinates and are returned as local coordinates. + * + * \param lattice pointer to the lattice + * \param ind global coordinates of the lattice site (Input) + * \param grid local coordinates of the lattice site (Output) + * \return index of the node for the lattice site + */ + int map_lattice_to_node(int *ind, int *grid) const; + + /********************** static Functions **********************/ + + /** Map a spatial position to the surrounding lattice sites. + * + * This function takes a global spatial position and determines the + * surrounding elementary cell of the lattice for this position. + * The distance fraction in each direction is also calculated. + *
Remarks: + *
    + *
  • The spatial position is given in global coordinates.
  • + *
  • The lattice sites of the elementary cell are returned as local + * indices
  • + *
+ * \param pos spatial position (Input) + * \param ind global index of the lower left lattice site (Output) + * \param delta distance fraction of pos from the surrounding + * elementary cell, 6 directions (Output) + * \param tmp_agrid lattice mesh distance + */ + static void map_position_to_lattice_global(Vector3d &pos, int ind[3], + double delta[6], double tmp_agrid); }; #endif /* LATTICE_HPP */ diff --git a/src/core/layered.cpp b/src/core/layered.cpp index 1436b31b0e..0aa273f8ed 100644 --- a/src/core/layered.cpp +++ b/src/core/layered.cpp @@ -312,7 +312,8 @@ void layered_topology_init(CellPList *old) { /* check node grid. All we can do is 1x1xn. */ if (node_grid[0] != 1 || node_grid[1] != 1) { runtimeErrorMsg() << "selected node grid is not suitable for layered cell " - "structure (needs 1x1x" << n_nodes << " grid"; + "structure (needs 1x1x" + << n_nodes << " grid"; node_grid[0] = node_grid[1] = 1; node_grid[2] = n_nodes; } diff --git a/src/core/layered.hpp b/src/core/layered.hpp index c1e237e9ef..48f4e4f4a6 100644 --- a/src/core/layered.hpp +++ b/src/core/layered.hpp @@ -1,26 +1,28 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file layered.hpp - The layered cellsystem. This cellsystem is a combination of a single processor n-squared method along x and y, - and a multiprocessor domain decomposition along z. Therefore only \f$1\times 1\times N\f$ processors grids are + The layered cellsystem. This cellsystem is a combination of a single + processor n-squared method along x and y, + and a multiprocessor domain decomposition along z. Therefore only \f$1\times + 1\times N\f$ processors grids are allowed for this cellsystem. The implementation is pretty similar to \ref domain_decomposition.hpp "domain_decomposition.h". */ diff --git a/src/core/lb-d3q19.cpp b/src/core/lb-d3q19.cpp index 6e95542ef5..6a7852bc2f 100644 --- a/src/core/lb-d3q19.cpp +++ b/src/core/lb-d3q19.cpp @@ -1,2 +1 @@ #include "config.hpp" - diff --git a/src/core/lb.cpp b/src/core/lb.cpp index 04d62a9963..b662770200 100755 --- a/src/core/lb.cpp +++ b/src/core/lb.cpp @@ -2127,7 +2127,8 @@ void lb_release() { release_halo_communication(&update_halo_comm); } /***********************************************************************/ /*@{*/ void lb_calc_n_from_rho_j_pi(const Lattice::index_t index, const double rho, - const std::array &j, const std::array &pi) { + const std::array &j, + const std::array &pi) { int i; double local_rho, local_j[3], local_pi[6], trace; const double avg_rho = lbpar.rho * lbpar.agrid * lbpar.agrid * lbpar.agrid; @@ -3046,30 +3047,31 @@ void calc_particle_lattice_ia() { /*@}*/ -/*@}*/ -void print_fluid() { - for (int x=0; x < lblattice.halo_grid[0]; ++x) { - for (int y=0; y < lblattice.halo_grid[1]; ++y) { - for (int z=0; z -struct LB_Model { +template struct LB_Model { /** number of velocities */ static const int n_veloc = static_cast(N_vel); @@ -121,7 +119,7 @@ struct LB_FluidNode { /** local force density */ double force_density[3]; -#ifdef VIRTUAL_SITES_INERTIALESS_TRACERS +#ifdef VIRTUAL_SITES_INERTIALESS_TRACERS // For particle update, we need the force on the nodes in LBM // Yet, Espresso resets the force immediately after the LBM update // Therefore we save it here @@ -152,9 +150,11 @@ typedef struct { * lead to numerical artifacts with low order integrators */ double friction; - /** external force density applied to the fluid at each lattice site (MD units) */ - double ext_force_density[3]; /* Open question: Do we want a local force or global - force? */ + /** external force density applied to the fluid at each lattice site (MD + * units) */ + double + ext_force_density[3]; /* Open question: Do we want a local force or global + force? */ double rho_lb_units; /** relaxation of the odd kinetic modes */ double gamma_odd; @@ -209,7 +209,8 @@ extern int transfer_momentum; /** Updates the Lattice Boltzmann system for one time step. * This function performs the collision step and the streaming step. - * If external force densities are present, they are applied prior to the collisions. + * If external force densities are present, they are applied prior to the + * collisions. * If boundaries are present, it also applies the boundary conditions. */ void lattice_boltzmann_update(); @@ -240,11 +241,13 @@ int lb_sanity_checks(); @param pi local fluid pressure */ void lb_calc_n_from_rho_j_pi(const Lattice::index_t index, const double rho, - const std::array &j, const std::array &pi); + const std::array &j, + const std::array &pi); /** Propagates the Lattice Boltzmann system for one time step. * This function performs the collision step and the streaming step. - * If external force densities are present, they are applied prior to the collisions. + * If external force densities are present, they are applied prior to the + * collisions. * If boundaries are present, it also applies the boundary conditions. */ void lb_propagate(); @@ -288,13 +291,13 @@ inline void lb_calc_local_rho(Lattice::index_t index, double *rho) { double avg_rho = lbpar.rho * lbpar.agrid * lbpar.agrid * lbpar.agrid; - *rho = avg_rho + lbfluid[0][index] + lbfluid[1][index] + - lbfluid[2][index] + lbfluid[3][index] + lbfluid[4][index] + - lbfluid[5][index] + lbfluid[6][index] + lbfluid[7][index] + - lbfluid[8][index] + lbfluid[9][index] + lbfluid[10][index] + - lbfluid[11][index] + lbfluid[12][index] + lbfluid[13][index] + - lbfluid[14][index] + lbfluid[15][index] + lbfluid[16][index] + - lbfluid[17][index] + lbfluid[18][index]; + *rho = avg_rho + lbfluid[0][index] + lbfluid[1][index] + lbfluid[2][index] + + lbfluid[3][index] + lbfluid[4][index] + lbfluid[5][index] + + lbfluid[6][index] + lbfluid[7][index] + lbfluid[8][index] + + lbfluid[9][index] + lbfluid[10][index] + lbfluid[11][index] + + lbfluid[12][index] + lbfluid[13][index] + lbfluid[14][index] + + lbfluid[15][index] + lbfluid[16][index] + lbfluid[17][index] + + lbfluid[18][index]; } /** Calculate the local fluid momentum. @@ -488,7 +491,7 @@ int lb_lbfluid_set_friction(double *p_friction); int lb_lbfluid_set_couple_flag(int couple_flag); int lb_lbfluid_set_agrid(double p_agrid); int lb_lbfluid_set_ext_force_density(int component, double p_fx, double p_fy, - double p_fz); + double p_fz); int lb_lbfluid_set_tau(double p_tau); int lb_lbfluid_set_remove_momentum(void); int lb_lbfluid_get_agrid(double *p_agrid); @@ -534,7 +537,7 @@ int lb_lbnode_set_pop(int *ind, double *pop); * lattice. Note that it can lead to undefined behaviour if the * position is not within the local lattice. This version of the function * can be called without the position needing to be on the local processor */ -int lb_lbfluid_get_interpolated_velocity_global(Vector3d& p, double* v); +int lb_lbfluid_get_interpolated_velocity_global(Vector3d &p, double *v); #endif diff --git a/src/core/lbboundaries.cpp b/src/core/lbboundaries.cpp index a1e6fafe3d..1fd40a4f3b 100644 --- a/src/core/lbboundaries.cpp +++ b/src/core/lbboundaries.cpp @@ -30,18 +30,18 @@ #include "communication.hpp" #include "electrokinetics.hpp" #include "electrokinetics_pdb_parse.hpp" +#include "grid.hpp" #include "initialize.hpp" #include "interaction_data.hpp" #include "lb.hpp" #include "lbboundaries.hpp" #include "lbboundaries/LBBoundary.hpp" #include "lbgpu.hpp" -#include "grid.hpp" #include +#include #include #include -#include namespace LBBoundaries { diff --git a/src/core/lbboundaries.hpp b/src/core/lbboundaries.hpp index 3e21db3463..91d91d4aad 100644 --- a/src/core/lbboundaries.hpp +++ b/src/core/lbboundaries.hpp @@ -38,17 +38,17 @@ #ifndef LBBOUNDARIES_H #define LBBOUNDARIES_H -#include "utils.hpp" #include "lbboundaries/LBBoundary.hpp" +#include "utils.hpp" #include "utils/Span.hpp" #include namespace LBBoundaries { - using LB_Fluid = std::array, 19>; +using LB_Fluid = std::array, 19>; - extern std::vector> lbboundaries; +extern std::vector> lbboundaries; #if defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) /*@}*/ @@ -57,7 +57,7 @@ namespace LBBoundaries { * and marks them with a corresponding flag. */ void lb_init_boundaries(); -void lbboundary_mindist_position(const Vector3d& pos, double *mindist, +void lbboundary_mindist_position(const Vector3d &pos, double *mindist, double distvec[3], int *no); int lbboundary_get_force(int no, double *f); @@ -73,11 +73,10 @@ void remove(const std::shared_ptr &); * * [cf. Ladd and Verberg, J. Stat. Phys. 104(5/6):1191-1251, 2001] */ - void lb_bounce_back(LB_Fluid &lbfluid); +void lb_bounce_back(LB_Fluid &lbfluid); #endif /* LB_BOUNDARIES */ - #endif // (LB_BOUNDARIES) || (LB_BOUNDARIES_GPU) } #endif /* LB_BOUNDARIES_H */ diff --git a/src/core/lbboundaries/LBBoundary.cpp b/src/core/lbboundaries/LBBoundary.cpp index d20af85c00..c59b9c5a75 100644 --- a/src/core/lbboundaries/LBBoundary.cpp +++ b/src/core/lbboundaries/LBBoundary.cpp @@ -3,16 +3,17 @@ #include "lbboundaries.hpp" namespace LBBoundaries { - // Vector3d LBBoundary::get_force() { - // double tmp_force[3]; - // int n = 0; - // for (auto it = lbboundaries.begin(); it != lbboundaries.end(); ++it, ++n) { - // if (&(**it) == this) - // break; - // } - // if (n == lbboundaries.size()) - // throw std::runtime_error("You probably tried to get the force of an lbboundary that was not added to system.lbboundaries."); - // lbboundary_get_force(n, tmp_force); - // return Vector3d{tmp_force[0], tmp_force[1], tmp_force[2]}; - // } +// Vector3d LBBoundary::get_force() { +// double tmp_force[3]; +// int n = 0; +// for (auto it = lbboundaries.begin(); it != lbboundaries.end(); ++it, ++n) { +// if (&(**it) == this) +// break; +// } +// if (n == lbboundaries.size()) +// throw std::runtime_error("You probably tried to get the force of an +// lbboundary that was not added to system.lbboundaries."); +// lbboundary_get_force(n, tmp_force); +// return Vector3d{tmp_force[0], tmp_force[1], tmp_force[2]}; +// } } diff --git a/src/core/lbboundaries/LBBoundary.hpp b/src/core/lbboundaries/LBBoundary.hpp index fb662d2056..de0a546a55 100644 --- a/src/core/lbboundaries/LBBoundary.hpp +++ b/src/core/lbboundaries/LBBoundary.hpp @@ -3,23 +3,21 @@ #include +#include "Vector.hpp" #include "config.hpp" #include "shapes/NoWhere.hpp" #include "shapes/Shape.hpp" -#include "Vector.hpp" - namespace LBBoundaries { #if defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) -int lbboundary_get_force(void* lbb, double *f); +int lbboundary_get_force(void *lbb, double *f); void lb_init_boundaries(); #endif class LBBoundary { public: LBBoundary() : m_shape(std::make_shared()), - m_velocity(Vector3d{0, 0, 0}), - m_force(Vector3d{0, 0, 0}) { + m_velocity(Vector3d{0, 0, 0}), m_force(Vector3d{0, 0, 0}) { #ifdef EK_BOUNDARIES m_charge_density = 0.0; m_net_charge = 0.0; @@ -31,7 +29,6 @@ class LBBoundary { return m_shape->calculate_dist(pos, dist, vec); } - void set_shape(std::shared_ptr const &shape) { m_shape = shape; } @@ -42,13 +39,13 @@ class LBBoundary { lb_init_boundaries(); #endif } - void reset_force() { m_force = Vector3d{0,0,0}; } + void reset_force() { m_force = Vector3d{0, 0, 0}; } Shapes::Shape const &shape() const { return *m_shape; } Vector3d &velocity() { return m_velocity; } Vector3d &force() { return m_force; } Vector3d get_force() { -#if defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) +#if defined(LB_BOUNDARIES) || defined(LB_BOUNDARIES_GPU) double tmp_force[3]; lbboundary_get_force(this, tmp_force); return Vector3d{tmp_force[0], tmp_force[1], tmp_force[2]}; @@ -57,8 +54,12 @@ class LBBoundary { #endif } -#ifdef EK_BOUNDARIES //TODO: ugly. Better would be a class EKBoundaries, deriving from LBBoundaries, but that requires completely different initialization infrastructure. - void set_charge_density(float charge_density) { m_charge_density = charge_density; } +#ifdef EK_BOUNDARIES // TODO: ugly. Better would be a class EKBoundaries, + // deriving from LBBoundaries, but that requires completely + // different initialization infrastructure. + void set_charge_density(float charge_density) { + m_charge_density = charge_density; + } void set_net_charge(float net_charge) { m_net_charge = net_charge; } float &charge_density() { return m_charge_density; } @@ -68,14 +69,19 @@ class LBBoundary { private: /** Private methods */ /* The actual boundary */ - std::shared_ptr<::LBBoundaries::LBBoundary> m_lbboundary; // TODO probably a brainfart (and named wrong) + std::shared_ptr<::LBBoundaries::LBBoundary> + m_lbboundary; // TODO probably a brainfart (and named wrong) /** Private data members */ - std::shared_ptr m_shape; //TODO: I dont like this being a pointer just to get around the virtual limitations + std::shared_ptr m_shape; // TODO: I dont like this being a + // pointer just to get around the + // virtual limitations Vector3d m_velocity; Vector3d m_force; -#ifdef EK_BOUNDARIES //TODO: ugly. Better would be a class EKBoundaries, deriving from LBBoundaries, but that requires completely different initialization infrastructure. +#ifdef EK_BOUNDARIES // TODO: ugly. Better would be a class EKBoundaries, + // deriving from LBBoundaries, but that requires completely + // different initialization infrastructure. float m_charge_density; float m_net_charge; #endif diff --git a/src/core/lbgpu.cpp b/src/core/lbgpu.cpp index e65d90e721..65f1bd8d83 100755 --- a/src/core/lbgpu.cpp +++ b/src/core/lbgpu.cpp @@ -1,18 +1,18 @@ -/* +/* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,125 +27,139 @@ #ifdef LB_GPU -#include "lbgpu.hpp" -#include "utils.hpp" #include "communication.hpp" -#include "thermostat.hpp" +#include "cuda_interface.hpp" +#include "global.hpp" #include "grid.hpp" #include "integrate.hpp" #include "interaction_data.hpp" -#include "particle_data.hpp" -#include "global.hpp" +#include "lb.hpp" #include "lbboundaries.hpp" -#include "cuda_interface.hpp" -#include "statistics.hpp" +#include "lbgpu.hpp" #include "partCfg_global.hpp" -#include "lb.hpp" +#include "particle_data.hpp" +#include "statistics.hpp" +#include "thermostat.hpp" +#include "utils.hpp" -#include #include +#include #include -#include #include +#include #include #ifndef D3Q19 #error The implementation only works for D3Q19 so far! #endif -#if (LB_COMPONENTS==1) -# define SC0 {0.0} -# define SC20 {0.0, 0.0} -# define SC1 {1.0} -# define SCM1 {-1.0} -#endif -#if (LB_COMPONENTS==2) -# define SC0 { 0.0 , 0.0 } -# define SC20 {0.0, 0.0, 0.0, 0.0} -# define SC1 { 1.0 , 1.0 } -# define SCM1 { -1.0, -1.0 } -#endif - +#if (LB_COMPONENTS == 1) +#define SC0 \ + { 0.0 } +#define SC20 \ + { 0.0, 0.0 } +#define SC1 \ + { 1.0 } +#define SCM1 \ + { -1.0 } +#endif +#if (LB_COMPONENTS == 2) +#define SC0 \ + { 0.0, 0.0 } +#define SC20 \ + { 0.0, 0.0, 0.0, 0.0 } +#define SC1 \ + { 1.0, 1.0 } +#define SCM1 \ + { -1.0, -1.0 } +#endif /** Struct holding the Lattice Boltzmann parameters */ -// LB_parameters_gpu lbpar_gpu = { .rho=SC0, .mu=SC0, .viscosity=SC0, .gamma_shear=SC0, .gamma_bulk=SC0, -// .gamma_odd=SC0,.gamma_even=SC0, .agrid=0.0, .tau=-1.0, .friction=SC0, .time_step=0.0, .lb_coupl_pref=SC1 , -// .lb_coupl_pref2=SC0, .bulk_viscosity=SCM1, .dim_x=0, .dim_y=0, .dim_z=0, .number_of_nodes=0, -// .number_of_particles=0, .fluct=0, .calc_val=1, .external_force=0, .ext_force={0.0, 0.0, 0.0}, +// LB_parameters_gpu lbpar_gpu = { .rho=SC0, .mu=SC0, .viscosity=SC0, +// .gamma_shear=SC0, .gamma_bulk=SC0, +// .gamma_odd=SC0,.gamma_even=SC0, .agrid=0.0, +// .tau=-1.0, .friction=SC0, .time_step=0.0, +// .lb_coupl_pref=SC1 , +// .lb_coupl_pref2=SC0, .bulk_viscosity=SCM1, +// .dim_x=0, .dim_y=0, .dim_z=0, +// .number_of_nodes=0, +// .number_of_particles=0, .fluct=0, +// .calc_val=1, .external_force=0, +// .ext_force={0.0, 0.0, 0.0}, // .your_seed=12345, .reinit=0, // #ifdef SHANCHEN // .coupling=SC20, .gamma_mobility=SC1 // #endif // }; LB_parameters_gpu lbpar_gpu = { - // rho - SC0, - // mu - SC0, - // viscosity - SC0, - // gamma_shear - SC0, - // gamma_bulk - SC0, - // gamma_odd - SC0, - // gamma_even - SC0, - //is_TRT - false, - // friction - SC0, - // lb_couple_switch - LB_COUPLE_TWO_POINT, - // lb_coupl_pref - SC0, - // lb_coupl_pref2 - SC0, - // bulk_viscosity - SCM1, - // agrid - -1.0, - // tau - -1.0, - // time_step - 0.0, - // dim_x; - 0, - // dim_y; - 0, - // dim_z; - 0, - // number_of_nodes - 0, - // number_of_particles - 0, + // rho + SC0, + // mu + SC0, + // viscosity + SC0, + // gamma_shear + SC0, + // gamma_bulk + SC0, + // gamma_odd + SC0, + // gamma_even + SC0, + // is_TRT + false, + // friction + SC0, + // lb_couple_switch + LB_COUPLE_TWO_POINT, + // lb_coupl_pref + SC0, + // lb_coupl_pref2 + SC0, + // bulk_viscosity + SCM1, + // agrid + -1.0, + // tau + -1.0, + // time_step + 0.0, + // dim_x; + 0, + // dim_y; + 0, + // dim_z; + 0, + // number_of_nodes + 0, + // number_of_particles + 0, #ifdef LB_BOUNDARIES_GPU - // number_of_boundnodes - 0, + // number_of_boundnodes + 0, #endif - // fluct - 0, - // calc_val - 1, - // external_force - 0, - // ext_force - {0.0, 0.0, 0.0}, - // your_seed - 12345, - // reinit - 0, + // fluct + 0, + // calc_val + 1, + // external_force + 0, + // ext_force + {0.0, 0.0, 0.0}, + // your_seed + 12345, + // reinit + 0, #ifdef SHANCHEN - // gamma_mobility - SC1, - // mobility - SC1, - // coupling - SC20, - // remove_momentum - 0 -#endif // SHANCHEN + // gamma_mobility + SC1, + // mobility + SC1, + // coupling + SC20, + // remove_momentum + 0 +#endif // SHANCHEN }; /** this is the array that stores the hydrodynamic fields for the output */ @@ -158,18 +172,17 @@ int transfer_momentum_gpu = 0; static int max_ran = 1000000; /*@}*/ -//static double tau; +// static double tau; /** measures the MD time since the last fluid update */ static int fluidstep = 0; /** c_sound_square in LB units*/ -static float c_sound_sq = 1.0f/3.0f; +static float c_sound_sq = 1.0f / 3.0f; -//clock_t start, end; +// clock_t start, end; int i; - int n_extern_node_force_densities = 0; LB_extern_nodeforcedensity_gpu *host_extern_node_force_densities = nullptr; int ek_initialized = 0; @@ -183,45 +196,45 @@ int ek_initialized = 0; and we reset it only when the last call to a LB function [lattice_boltzmann_update_gpu()] is performed within integrate_vv() */ -void lattice_boltzmann_calc_shanchen_gpu(void){ +void lattice_boltzmann_calc_shanchen_gpu(void) { - int factor = (int)round(lbpar_gpu.tau/time_step); + int factor = (int)round(lbpar_gpu.tau / time_step); - if (fluidstep+1 >= factor) - lb_calc_shanchen_GPU(); + if (fluidstep + 1 >= factor) + lb_calc_shanchen_GPU(); } -#endif //SHANCHEN +#endif // SHANCHEN /** lattice boltzmann update gpu called from integrate.cpp */ void lattice_boltzmann_update_gpu() { - int factor = (int)round(lbpar_gpu.tau/time_step); + int factor = (int)round(lbpar_gpu.tau / time_step); fluidstep += 1; - if (fluidstep>=factor) { + if (fluidstep >= factor) { - fluidstep=0; + fluidstep = 0; lb_integrate_GPU(); #ifdef SHANCHEN - if(lbpar_gpu.remove_momentum) lb_remove_fluid_momentum_GPU(); + if (lbpar_gpu.remove_momentum) + lb_remove_fluid_momentum_GPU(); #endif - LB_TRACE (fprintf(stderr,"lb_integrate_GPU \n")); - + LB_TRACE(fprintf(stderr, "lb_integrate_GPU \n")); } } /** (re-) allocation of the memory needed for the particles (cpu part) */ -void lb_realloc_particles_gpu(){ +void lb_realloc_particles_gpu() { lbpar_gpu.number_of_particles = n_part; - LB_TRACE (printf("#particles realloc\t %u \n", lbpar_gpu.number_of_particles)); + LB_TRACE(printf("#particles realloc\t %u \n", lbpar_gpu.number_of_particles)); lbpar_gpu.your_seed = (unsigned int)std::random_device{}(); - LB_TRACE (fprintf(stderr,"test your_seed %u \n", lbpar_gpu.your_seed)); + LB_TRACE(fprintf(stderr, "test your_seed %u \n", lbpar_gpu.your_seed)); lb_realloc_particles_GPU_leftovers(&lbpar_gpu); } @@ -230,133 +243,162 @@ void lb_realloc_particles_gpu(){ void lb_reinit_fluid_gpu() { lb_reinit_parameters_gpu(); - if(lbpar_gpu.number_of_nodes != 0){ + if (lbpar_gpu.number_of_nodes != 0) { lb_reinit_GPU(&lbpar_gpu); lb_reinit_extern_nodeforce_GPU(&lbpar_gpu); lbpar_gpu.reinit = 1; } - LB_TRACE (fprintf(stderr,"lb_reinit_fluid_gpu \n")); + LB_TRACE(fprintf(stderr, "lb_reinit_fluid_gpu \n")); } /** Release the fluid. */ /*not needed in Espresso but still not deleted. - Despite the name (TODO: change it), it releases + Despite the name (TODO: change it), it releases only the fluid-related memory on the gpu.*/ -void lb_release_gpu(){ +void lb_release_gpu() { - if(host_nodes !=nullptr) { free(host_nodes); host_nodes=nullptr ;} - if(host_values!=nullptr) { free(host_values); host_values=nullptr;} -// if(host_forces!=nullptr) free(host_forces); -// if(host_data !=nullptr) free(host_data); + if (host_nodes != nullptr) { + free(host_nodes); + host_nodes = nullptr; + } + if (host_values != nullptr) { + free(host_values); + host_values = nullptr; + } + // if(host_forces!=nullptr) free(host_forces); + // if(host_data !=nullptr) free(host_data); } /** (Re-)initializes the fluid. */ void lb_reinit_parameters_gpu() { int ii; lbpar_gpu.time_step = (float)time_step; - for(ii=0;ii 0.0 && lbpar_gpu.agrid > 0.0 && lbpar_gpu.tau > 0.0 ) { + + if (lbpar_gpu.viscosity[ii] > 0.0 && lbpar_gpu.agrid > 0.0 && + lbpar_gpu.tau > 0.0) { /* Eq. (80) Duenweg, Schiller, Ladd, PRE 76(3):036704 (2007). */ - lbpar_gpu.gamma_shear[ii] = 1. - 2./(6.*lbpar_gpu.viscosity[ii]*lbpar_gpu.tau/(lbpar_gpu.agrid*lbpar_gpu.agrid) + 1.); + lbpar_gpu.gamma_shear[ii] = + 1. - + 2. / (6. * lbpar_gpu.viscosity[ii] * lbpar_gpu.tau / + (lbpar_gpu.agrid * lbpar_gpu.agrid) + + 1.); } - + if (lbpar_gpu.bulk_viscosity[ii] > 0.0) { /* Eq. (81) Duenweg, Schiller, Ladd, PRE 76(3):036704 (2007). */ - lbpar_gpu.gamma_bulk[ii] = 1. - 2./(9.*lbpar_gpu.bulk_viscosity[ii]*lbpar_gpu.tau/(lbpar_gpu.agrid*lbpar_gpu.agrid) + 1.); + lbpar_gpu.gamma_bulk[ii] = + 1. - + 2. / (9. * lbpar_gpu.bulk_viscosity[ii] * lbpar_gpu.tau / + (lbpar_gpu.agrid * lbpar_gpu.agrid) + + 1.); } - //By default, gamma_even and gamma_odd are chosen such that the MRT becomes - //a TRT with ghost mode relaxation factors that minimize unphysical wall - //slip at bounce-back boundaries. For the relation between the gammas - //achieving this, consult + // By default, gamma_even and gamma_odd are chosen such that the MRT becomes + // a TRT with ghost mode relaxation factors that minimize unphysical wall + // slip at bounce-back boundaries. For the relation between the gammas + // achieving this, consult // D. d’Humières, I. Ginzburg, Comp. & Math. w. App. 58(5):823–840 (2009) - //Note that the relaxation operator in Espresso is defined as + // Note that the relaxation operator in Espresso is defined as // m* = m_eq + gamma * (m - m_eq) - //as opposed to this reference, where + // as opposed to this reference, where // m* = m + lambda * (m - m_eq) - + if (lbpar_gpu.is_TRT) { lbpar_gpu.gamma_bulk[ii] = lbpar_gpu.gamma_shear[ii]; lbpar_gpu.gamma_even[ii] = lbpar_gpu.gamma_shear[ii]; - lbpar_gpu.gamma_odd[ii] = -(7.0f*lbpar_gpu.gamma_even[ii]+1.0f)/(lbpar_gpu.gamma_even[ii]+7.0f); - //lbpar_gpu.gamma_odd[ii] = lbpar_gpu.gamma_shear[ii]; //uncomment for BGK + lbpar_gpu.gamma_odd[ii] = -(7.0f * lbpar_gpu.gamma_even[ii] + 1.0f) / + (lbpar_gpu.gamma_even[ii] + 7.0f); + // lbpar_gpu.gamma_odd[ii] = lbpar_gpu.gamma_shear[ii]; //uncomment for + // BGK } - - //lbpar_gpu.gamma_even[ii] = 0.0; //uncomment for special case of BGK - //lbpar_gpu.gamma_odd[ii] = 0.0; - //lbpar_gpu.gamma_shear[ii] = 0.0; - //lbpar_gpu.gamma_bulk[ii] = 0.0; - - //printf("gamma_shear=%e\n", lbpar_gpu.gamma_shear[ii]); - //printf("gamma_bulk=%e\n", lbpar_gpu.gamma_bulk[ii]); - //printf("TRT gamma_odd=%e\n", lbpar_gpu.gamma_odd[ii]); - //printf("TRT gamma_even=%e\n", lbpar_gpu.gamma_even[ii]); - //printf("\n"); + +// lbpar_gpu.gamma_even[ii] = 0.0; //uncomment for special case of BGK +// lbpar_gpu.gamma_odd[ii] = 0.0; +// lbpar_gpu.gamma_shear[ii] = 0.0; +// lbpar_gpu.gamma_bulk[ii] = 0.0; + +// printf("gamma_shear=%e\n", lbpar_gpu.gamma_shear[ii]); +// printf("gamma_bulk=%e\n", lbpar_gpu.gamma_bulk[ii]); +// printf("TRT gamma_odd=%e\n", lbpar_gpu.gamma_odd[ii]); +// printf("TRT gamma_even=%e\n", lbpar_gpu.gamma_even[ii]); +// printf("\n"); #ifdef SHANCHEN if (lbpar_gpu.mobility[0] > 0.0) { - lbpar_gpu.gamma_mobility[0] = 1. - 2./(6.*lbpar_gpu.mobility[0]*lbpar_gpu.tau/(lbpar_gpu.agrid*lbpar_gpu.agrid) + 1.); + lbpar_gpu.gamma_mobility[0] = + 1. - + 2. / (6. * lbpar_gpu.mobility[0] * lbpar_gpu.tau / + (lbpar_gpu.agrid * lbpar_gpu.agrid) + + 1.); } #endif - if (temperature > 0.0) { /* fluctuating hydrodynamics ? */ - + if (temperature > 0.0) { /* fluctuating hydrodynamics ? */ + lbpar_gpu.fluct = 1; - LB_TRACE (fprintf(stderr, "fluct on \n")); + LB_TRACE(fprintf(stderr, "fluct on \n")); /* Eq. (51) Duenweg, Schiller, Ladd, PRE 76(3):036704 (2007).*/ /* Note that the modes are not normalized as in the paper here! */ - lbpar_gpu.mu[ii] = (float)temperature*lbpar_gpu.tau*lbpar_gpu.tau/c_sound_sq/(lbpar_gpu.agrid*lbpar_gpu.agrid); - + lbpar_gpu.mu[ii] = (float)temperature * lbpar_gpu.tau * lbpar_gpu.tau / + c_sound_sq / (lbpar_gpu.agrid * lbpar_gpu.agrid); + /* lb_coupl_pref is stored in MD units (force) * Eq. (16) Ahlrichs and Duenweg, JCP 111(17):8225 (1999). * The factor 12 comes from the fact that we use random numbers * from -0.5 to 0.5 (equally distributed) which have variance 1/12. * time_step comes from the discretization. */ - - lbpar_gpu.lb_coupl_pref[ii] = sqrtf(12.f*2.f*lbpar_gpu.friction[ii]*(float)temperature/lbpar_gpu.time_step); - lbpar_gpu.lb_coupl_pref2[ii] = sqrtf(2.f*lbpar_gpu.friction[ii]*(float)temperature/lbpar_gpu.time_step); - + + lbpar_gpu.lb_coupl_pref[ii] = + sqrtf(12.f * 2.f * lbpar_gpu.friction[ii] * (float)temperature / + lbpar_gpu.time_step); + lbpar_gpu.lb_coupl_pref2[ii] = + sqrtf(2.f * lbpar_gpu.friction[ii] * (float)temperature / + lbpar_gpu.time_step); + } else { /* no fluctuations at zero temperature */ lbpar_gpu.fluct = 0; lbpar_gpu.lb_coupl_pref[ii] = 0.0; lbpar_gpu.lb_coupl_pref2[ii] = 0.0; } - LB_TRACE (fprintf(stderr,"lb_reinit_prarameters_gpu \n")); + LB_TRACE(fprintf(stderr, "lb_reinit_prarameters_gpu \n")); } - #ifdef ELECTROKINETICS if (ek_initialized) { - lbpar_gpu.dim_x = (unsigned int) round(box_l[0] / lbpar_gpu.agrid); //TODO code duplication with lb.c start - lbpar_gpu.dim_y = (unsigned int) round(box_l[1] / lbpar_gpu.agrid); - lbpar_gpu.dim_z = (unsigned int) round(box_l[2] / lbpar_gpu.agrid); - + lbpar_gpu.dim_x = (unsigned int)round( + box_l[0] / lbpar_gpu.agrid); // TODO code duplication with lb.c start + lbpar_gpu.dim_y = (unsigned int)round(box_l[1] / lbpar_gpu.agrid); + lbpar_gpu.dim_z = (unsigned int)round(box_l[2] / lbpar_gpu.agrid); + unsigned int tmp[3]; - + tmp[0] = lbpar_gpu.dim_x; tmp[1] = lbpar_gpu.dim_y; tmp[2] = lbpar_gpu.dim_z; - + /* sanity checks */ int dir; - - for (dir=0;dir<3;dir++) { - /* check if box_l is compatible with lattice spacing */ + + for (dir = 0; dir < 3; dir++) { + /* check if box_l is compatible with lattice spacing */ if (fabs(box_l[dir] - tmp[dir] * lbpar_gpu.agrid) > 1.0e-3) { - runtimeErrorMsg() <<"Lattice spacing lbpar_gpu.agrid= "<< lbpar_gpu.agrid << " is incompatible with box_l[" << dir << "]=" << box_l[dir]; + runtimeErrorMsg() << "Lattice spacing lbpar_gpu.agrid= " + << lbpar_gpu.agrid << " is incompatible with box_l[" + << dir << "]=" << box_l[dir]; } } - - lbpar_gpu.number_of_nodes = lbpar_gpu.dim_x * lbpar_gpu.dim_y * lbpar_gpu.dim_z; - lbpar_gpu.tau = (float) time_step; //TODO code duplication with lb.c end + + lbpar_gpu.number_of_nodes = + lbpar_gpu.dim_x * lbpar_gpu.dim_y * lbpar_gpu.dim_z; + lbpar_gpu.tau = (float)time_step; // TODO code duplication with lb.c end } #endif - - LB_TRACE (fprintf(stderr,"lb_reinit_prarameters_gpu \n")); + + LB_TRACE(fprintf(stderr, "lb_reinit_prarameters_gpu \n")); reinit_parameters_GPU(&lbpar_gpu); } @@ -373,7 +415,7 @@ void lb_init_gpu() { lb_realloc_particles_gpu(); lb_init_GPU(&lbpar_gpu); - + gpu_init_particle_comm(); cuda_bcast_global_part_params(); @@ -382,68 +424,74 @@ void lb_init_gpu() { /*@}*/ -int lb_lbnode_set_extforce_density_GPU(int ind[3], double f[3]) -{ - if ( ind[0] < 0 || ind[0] >= int(lbpar_gpu.dim_x) || - ind[1] < 0 || ind[1] >= int(lbpar_gpu.dim_y) || - ind[2] < 0 || ind[2] >= int(lbpar_gpu.dim_z) ) +int lb_lbnode_set_extforce_density_GPU(int ind[3], double f[3]) { + if (ind[0] < 0 || ind[0] >= int(lbpar_gpu.dim_x) || ind[1] < 0 || + ind[1] >= int(lbpar_gpu.dim_y) || ind[2] < 0 || + ind[2] >= int(lbpar_gpu.dim_z)) return ES_ERROR; - unsigned int index = - ind[0] + ind[1]*lbpar_gpu.dim_x + ind[2]*lbpar_gpu.dim_x*lbpar_gpu.dim_y; + unsigned int index = ind[0] + ind[1] * lbpar_gpu.dim_x + + ind[2] * lbpar_gpu.dim_x * lbpar_gpu.dim_y; + + size_t size_of_extforces = (n_extern_node_force_densities + 1) * + sizeof(LB_extern_nodeforcedensity_gpu); + host_extern_node_force_densities = + (LB_extern_nodeforcedensity_gpu *)Utils::realloc( + host_extern_node_force_densities, size_of_extforces); + + host_extern_node_force_densities[n_extern_node_force_densities] + .force_density[0] = (float)f[0]; + host_extern_node_force_densities[n_extern_node_force_densities] + .force_density[1] = (float)f[1]; + host_extern_node_force_densities[n_extern_node_force_densities] + .force_density[2] = (float)f[2]; - size_t size_of_extforces = (n_extern_node_force_densities+1)*sizeof(LB_extern_nodeforcedensity_gpu); - host_extern_node_force_densities = (LB_extern_nodeforcedensity_gpu*) Utils::realloc(host_extern_node_force_densities, size_of_extforces); - - host_extern_node_force_densities[n_extern_node_force_densities].force_density[0] = (float)f[0]; - host_extern_node_force_densities[n_extern_node_force_densities].force_density[1] = (float)f[1]; - host_extern_node_force_densities[n_extern_node_force_densities].force_density[2] = (float)f[2]; - host_extern_node_force_densities[n_extern_node_force_densities].index = index; n_extern_node_force_densities++; - - if(lbpar_gpu.external_force_density == 0)lbpar_gpu.external_force_density = 1; - lb_init_extern_nodeforcedensities_GPU(n_extern_node_force_densities, host_extern_node_force_densities, &lbpar_gpu); + if (lbpar_gpu.external_force_density == 0) + lbpar_gpu.external_force_density = 1; + + lb_init_extern_nodeforcedensities_GPU(n_extern_node_force_densities, + host_extern_node_force_densities, + &lbpar_gpu); return ES_OK; } -void lb_GPU_sanity_checks() -{ - if(this_node == 0){ +void lb_GPU_sanity_checks() { + if (this_node == 0) { if (lbpar_gpu.agrid < 0.0) { - runtimeErrorMsg() <<"Lattice Boltzmann agrid not set"; + runtimeErrorMsg() << "Lattice Boltzmann agrid not set"; } if (lbpar_gpu.tau < 0.0) { - runtimeErrorMsg() <<"Lattice Boltzmann time step not set"; + runtimeErrorMsg() << "Lattice Boltzmann time step not set"; } - for(int i=0;i> new_velocity(n_part); size_t i = 0; @@ -460,9 +508,10 @@ void lb_lbfluid_particles_add_momentum(float momentum[3]) { } } -void lb_lbfluid_calc_linear_momentum ( float momentum[3], int include_particles, int include_lbfluid ) -{ - auto linear_momentum = calc_linear_momentum(include_particles, include_lbfluid); +void lb_lbfluid_calc_linear_momentum(float momentum[3], int include_particles, + int include_lbfluid) { + auto linear_momentum = + calc_linear_momentum(include_particles, include_lbfluid); momentum[0] = linear_momentum[0]; momentum[1] = linear_momentum[1]; momentum[2] = linear_momentum[2]; diff --git a/src/core/lbgpu.hpp b/src/core/lbgpu.hpp index f313e92633..fdd0bdf722 100755 --- a/src/core/lbgpu.hpp +++ b/src/core/lbgpu.hpp @@ -1,18 +1,18 @@ -/* +/* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -20,14 +20,15 @@ /** \file lbgpu.hpp * Header file for lbgpu.cpp * - * This is the header file for the Lattice Boltzmann implementation in lbgpu_cfile.cpp + * This is the header file for the Lattice Boltzmann implementation in + * lbgpu_cfile.cpp */ #ifndef LB_GPU_H #define LB_GPU_H -#include "utils.hpp" #include "config.hpp" +#include "utils.hpp" #ifdef LB_GPU /* For the D3Q19 model most functions have a separate implementation @@ -38,8 +39,8 @@ #define LBQ 19 /** Note these are usef for binary logic so should be powers of 2 */ -#define LB_COUPLE_NULL 1 -#define LB_COUPLE_TWO_POINT 2 +#define LB_COUPLE_NULL 1 +#define LB_COUPLE_TWO_POINT 2 #define LB_COUPLE_THREE_POINT 4 /** \name Parameter fields for Lattice Boltzmann @@ -47,14 +48,16 @@ * to determine what actions have to take place upon change * of the respective parameter. */ /*@{*/ -#define LBPAR_DENSITY 0 /**< fluid density */ +#define LBPAR_DENSITY 0 /**< fluid density */ #define LBPAR_VISCOSITY 1 /**< fluid kinematic viscosity */ -#define LBPAR_AGRID 2 /**< grid constant for fluid lattice */ -#define LBPAR_TAU 3 /**< time step for fluid propagation */ -#define LBPAR_FRICTION 4 /**< friction coefficient for viscous coupling between particles and fluid */ -#define LBPAR_EXTFORCE 5 /**< external force acting on the fluid */ -#define LBPAR_BULKVISC 6 /**< fluid bulk viscosity */ -#define LBPAR_BOUNDARY 7 /**< boundary parameters */ +#define LBPAR_AGRID 2 /**< grid constant for fluid lattice */ +#define LBPAR_TAU 3 /**< time step for fluid propagation */ +#define LBPAR_FRICTION \ + 4 /**< friction coefficient for viscous coupling between particles and fluid \ + */ +#define LBPAR_EXTFORCE 5 /**< external force acting on the fluid */ +#define LBPAR_BULKVISC 6 /**< fluid bulk viscosity */ +#define LBPAR_BOUNDARY 7 /**< boundary parameters */ #ifdef SHANCHEN #define LBPAR_COUPLING 8 #define LBPAR_MOBILITY 9 @@ -68,7 +71,8 @@ typedef float lbForceFloat; #endif /**-------------------------------------------------------------------------*/ -/** Data structure holding the parameters for the Lattice Boltzmann system for gpu. */ +/** Data structure holding the parameters for the Lattice Boltzmann system for + * gpu. */ typedef struct { /** number density (LJ units) */ float rho[LB_COMPONENTS]; @@ -83,7 +87,8 @@ typedef struct { /** */ float gamma_odd[LB_COMPONENTS]; float gamma_even[LB_COMPONENTS]; - /** flag determining whether gamma_shear, gamma_odd, and gamma_even are calculated + /** flag determining whether gamma_shear, gamma_odd, and gamma_even are + * calculated * from gamma_shear in such a way to yield a TRT LB with minimized slip at * bounce-back boundaries */ bool is_TRT; @@ -126,23 +131,25 @@ typedef struct { int external_force_density; - float ext_force_density[3*LB_COMPONENTS]; + float ext_force_density[3 * LB_COMPONENTS]; unsigned int your_seed; unsigned int reinit; #ifdef SHANCHEN - /** mobility. They are actually LB_COMPONENTS-1 in number, we leave LB_COMPONENTS here for practical reasons*/ + /** mobility. They are actually LB_COMPONENTS-1 in number, we leave + * LB_COMPONENTS here for practical reasons*/ float gamma_mobility[LB_COMPONENTS]; float mobility[LB_COMPONENTS]; - float coupling[LB_COMPONENTS*LB_COMPONENTS]; + float coupling[LB_COMPONENTS * LB_COMPONENTS]; int remove_momentum; -#endif // SHANCHEN +#endif // SHANCHEN } LB_parameters_gpu; -/** Data structure holding the conserved quantities for the Lattice Boltzmann system. */ +/** Data structure holding the conserved quantities for the Lattice Boltzmann + * system. */ typedef struct { /** density of the node */ @@ -152,19 +159,21 @@ typedef struct { float v[3]; } LB_rho_v_gpu; -/* this structure is almost duplicated for memory efficiency. When the stress - tensor element are needed at every timestep, this features should be explicitly +/* this structure is almost duplicated for memory efficiency. When the stress + tensor element are needed at every timestep, this features should be + explicitly switched on */ -typedef struct { +typedef struct { /** density of the node */ float rho[LB_COMPONENTS]; /** veolcity of the node */ float v[3]; /** pressure tensor */ - float pi[6]; + float pi[6]; } LB_rho_v_pi_gpu; -/** Data structure holding the velocity densities for the Lattice Boltzmann system. */ +/** Data structure holding the velocity densities for the Lattice Boltzmann + * system. */ typedef struct { /** velocity density of the node */ @@ -191,7 +200,8 @@ typedef struct { float *scforce_density; #if defined(VIRTUAL_SITES_INERTIALESS_TRACERS) || defined(EK_DEBUG) - // We need the node forces for the velocity interpolation at the virtual particles' position + // We need the node forces for the velocity interpolation at the virtual + // particles' position // However, LBM wants to reset them immediately after the LBM update // This variable keeps a backup lbForceFloat *force_density_buf; @@ -207,7 +217,6 @@ typedef struct { } LB_extern_nodeforcedensity_gpu; - void on_lb_params_change_gpu(int field); /************************************************************/ @@ -215,7 +224,7 @@ void on_lb_params_change_gpu(int field); /************************************************************/ /*@{*/ -/** +/** */ /** Switch indicating momentum exchange between particles and fluid */ @@ -228,7 +237,6 @@ extern LB_node_force_density_gpu node_f; extern int ek_initialized; #endif - /*@}*/ /************************************************************/ @@ -238,10 +246,10 @@ extern int ek_initialized; void lb_GPU_sanity_checks(); -void lb_get_device_values_pointer(LB_rho_v_gpu** pointeradress); -void lb_get_boundary_force_pointer(float** pointeradress); -void lb_get_lbpar_pointer(LB_parameters_gpu** pointeradress); -void lb_get_para_pointer(LB_parameters_gpu** pointeradress); +void lb_get_device_values_pointer(LB_rho_v_gpu **pointeradress); +void lb_get_boundary_force_pointer(float **pointeradress); +void lb_get_lbpar_pointer(LB_parameters_gpu **pointeradress); +void lb_get_para_pointer(LB_parameters_gpu **pointeradress); void lattice_boltzmann_update_gpu(); /** (Pre-)initializes data structures. */ @@ -275,43 +283,59 @@ void lattice_boltzmann_calc_shanchen_gpu(); #endif void lb_free_GPU(); void lb_get_values_GPU(LB_rho_v_pi_gpu *host_values); -void lb_print_node_GPU(int single_nodeindex, LB_rho_v_pi_gpu *host_print_values); +void lb_print_node_GPU(int single_nodeindex, + LB_rho_v_pi_gpu *host_print_values); #ifdef LB_BOUNDARIES_GPU -void lb_init_boundaries_GPU(int n_lb_boundaries, int number_of_boundnodes, int* host_boundary_node_list, int* host_boundary_index_list, float* lb_bounday_velocity); +void lb_init_boundaries_GPU(int n_lb_boundaries, int number_of_boundnodes, + int *host_boundary_node_list, + int *host_boundary_index_list, + float *lb_bounday_velocity); #endif -void lb_init_extern_nodeforcedensities_GPU(int n_extern_node_force_densities, LB_extern_nodeforcedensity_gpu *host_extern_node_force_densities, LB_parameters_gpu *lbpar_gpu); +void lb_init_extern_nodeforcedensities_GPU( + int n_extern_node_force_densities, + LB_extern_nodeforcedensity_gpu *host_extern_node_force_densities, + LB_parameters_gpu *lbpar_gpu); void lb_calc_particle_lattice_ia_gpu(bool couple_virtual); -void lb_calc_fluid_mass_GPU(double* mass); -void lb_calc_fluid_momentum_GPU(double* host_mom); +void lb_calc_fluid_mass_GPU(double *mass); +void lb_calc_fluid_momentum_GPU(double *host_mom); void lb_remove_fluid_momentum_GPU(void); -void lb_calc_fluid_temperature_GPU(double* host_temp); -void lb_get_boundary_flag_GPU(int single_nodeindex, unsigned int* host_flag); -void lb_get_boundary_flags_GPU(unsigned int* host_bound_array); +void lb_calc_fluid_temperature_GPU(double *host_temp); +void lb_get_boundary_flag_GPU(int single_nodeindex, unsigned int *host_flag); +void lb_get_boundary_flags_GPU(unsigned int *host_bound_array); -void lb_set_node_velocity_GPU(int single_nodeindex, float* host_velocity); -void lb_set_node_rho_GPU(int single_nodeindex, float* host_rho); +void lb_set_node_velocity_GPU(int single_nodeindex, float *host_velocity); +void lb_set_node_rho_GPU(int single_nodeindex, float *host_rho); void reinit_parameters_GPU(LB_parameters_gpu *lbpar_gpu); void lb_reinit_extern_nodeforce_GPU(LB_parameters_gpu *lbpar_gpu); void lb_reinit_GPU(LB_parameters_gpu *lbpar_gpu); int lb_lbnode_set_extforce_density_GPU(int ind[3], double f[3]); -void lb_gpu_get_boundary_forces(double* forces); -void lb_save_checkpoint_GPU(float *host_checkpoint_vd, unsigned int *host_checkpoint_seed, unsigned int *host_checkpoint_boundary, lbForceFloat *host_checkpoint_force); -void lb_load_checkpoint_GPU(float *host_checkpoint_vd, unsigned int *host_checkpoint_seed, unsigned int *host_checkpoint_boundary, lbForceFloat *host_checkpoint_force); -int lb_lbfluid_save_checkpoint_wrapper(char* filename, int binary); -int lb_lbfluid_load_checkpoint_wrapper(char* filename, int binary); +void lb_gpu_get_boundary_forces(double *forces); +void lb_save_checkpoint_GPU(float *host_checkpoint_vd, + unsigned int *host_checkpoint_seed, + unsigned int *host_checkpoint_boundary, + lbForceFloat *host_checkpoint_force); +void lb_load_checkpoint_GPU(float *host_checkpoint_vd, + unsigned int *host_checkpoint_seed, + unsigned int *host_checkpoint_boundary, + lbForceFloat *host_checkpoint_force); +int lb_lbfluid_save_checkpoint_wrapper(char *filename, int binary); +int lb_lbfluid_load_checkpoint_wrapper(char *filename, int binary); void lb_lbfluid_remove_total_momentum(); void lb_lbfluid_fluid_add_momentum(float momentum[3]); -void lb_lbfluid_calc_linear_momentum(float momentum[3], int include_particles, int include_lbfluid); +void lb_lbfluid_calc_linear_momentum(float momentum[3], int include_particles, + int include_lbfluid); void lb_lbfluid_particles_add_momentum(float velocity[3]); void lb_lbfluid_set_population(int[3], float[LBQ], int); void lb_lbfluid_get_population(int[3], float[LBQ], int); -void lb_lbfluid_get_interpolated_velocity_at_positions(double const *positions, double *velocities, int length); +void lb_lbfluid_get_interpolated_velocity_at_positions(double const *positions, + double *velocities, + int length); /*@{*/ diff --git a/src/core/lj.hpp b/src/core/lj.hpp index 92dd001db0..f7305b9f6e 100755 --- a/src/core/lj.hpp +++ b/src/core/lj.hpp @@ -31,10 +31,10 @@ * \ref forces.cpp */ -#include "utils.hpp" #include "debug.hpp" -#include "particle_data.hpp" #include "interaction_data.hpp" +#include "particle_data.hpp" +#include "utils.hpp" int lennard_jones_set_params(int part_type_a, int part_type_b, double eps, double sig, double cut, double shift, @@ -54,7 +54,8 @@ inline void add_lj_pair_force(const Particle *const p1, double r_off = dist - ia_params->LJ_offset; double frac2 = Utils::sqr(ia_params->LJ_sig / r_off); double frac6 = frac2 * frac2 * frac2; - double fac = 48.0 * ia_params->LJ_eps * frac6 * (frac6 - 0.5) / (r_off * dist); + double fac = + 48.0 * ia_params->LJ_eps * frac6 * (frac6 - 0.5) / (r_off * dist); #ifdef SHANCHEN if (ia_params->affinity_on == 1) { if (LB_COMPONENTS == 2) { @@ -108,7 +109,8 @@ inline double lj_pair_energy(const Particle *p1, const Particle *p2, double r_off = dist - ia_params->LJ_offset; double frac2 = Utils::sqr(ia_params->LJ_sig / r_off); double frac6 = frac2 * frac2 * frac2; - return 4.0 * ia_params->LJ_eps * (Utils::sqr(frac6) - frac6 + ia_params->LJ_shift); + return 4.0 * ia_params->LJ_eps * + (Utils::sqr(frac6) - frac6 + ia_params->LJ_shift); } return 0.0; } diff --git a/src/core/ljcos.cpp b/src/core/ljcos.cpp index c9082a75ce..e858fc9f22 100755 --- a/src/core/ljcos.cpp +++ b/src/core/ljcos.cpp @@ -1,53 +1,53 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#include "utils.hpp" #include "ljcos.hpp" +#include "utils.hpp" #ifdef LJCOS #include "communication.hpp" -int ljcos_set_params(int part_type_a, int part_type_b, - double eps, double sig, double cut, - double offset) -{ +int ljcos_set_params(int part_type_a, int part_type_b, double eps, double sig, + double cut, double offset) { double facsq; IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) return ES_ERROR; - data->LJCOS_eps = eps; - data->LJCOS_sig = sig; - data->LJCOS_cut = cut; + if (!data) + return ES_ERROR; + + data->LJCOS_eps = eps; + data->LJCOS_sig = sig; + data->LJCOS_cut = cut; data->LJCOS_offset = offset; /* Calculate dependent parameters */ - facsq = driwu2*Utils::sqr(sig); - data->LJCOS_rmin = sqrt(driwu2)*sig; - data->LJCOS_alfa = PI/(Utils::sqr(data->LJCOS_cut)-facsq); - data->LJCOS_beta = PI*(1.-(1./(Utils::sqr(data->LJCOS_cut)/facsq-1.))); + facsq = driwu2 * Utils::sqr(sig); + data->LJCOS_rmin = sqrt(driwu2) * sig; + data->LJCOS_alfa = PI / (Utils::sqr(data->LJCOS_cut) - facsq); + data->LJCOS_beta = + PI * (1. - (1. / (Utils::sqr(data->LJCOS_cut) / facsq - 1.))); /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); - + return ES_OK; } #endif diff --git a/src/core/ljcos.hpp b/src/core/ljcos.hpp index 676262af65..6cdb441987 100755 --- a/src/core/ljcos.hpp +++ b/src/core/ljcos.hpp @@ -50,7 +50,8 @@ inline void add_ljcos_pair_force(const Particle *const p1, /* cos part of ljcos potential. */ if (dist > ia_params->LJCOS_rmin + ia_params->LJCOS_offset) { fac = (r_off / dist) * ia_params->LJCOS_alfa * ia_params->LJCOS_eps * - (sin(ia_params->LJCOS_alfa * Utils::sqr(r_off) + ia_params->LJCOS_beta)); + (sin(ia_params->LJCOS_alfa * Utils::sqr(r_off) + + ia_params->LJCOS_beta)); for (j = 0; j < 3; j++) force[j] += fac * d[j]; } @@ -106,7 +107,8 @@ inline double ljcos_pair_energy(const Particle *p1, const Particle *p2, /* cosine part of the potential. */ else if (dist < (ia_params->LJCOS_cut + ia_params->LJCOS_offset)) { return .5 * ia_params->LJCOS_eps * - (cos(ia_params->LJCOS_alfa * Utils::sqr(r_off) + ia_params->LJCOS_beta) - + (cos(ia_params->LJCOS_alfa * Utils::sqr(r_off) + + ia_params->LJCOS_beta) - 1.); } /* this should not happen! */ diff --git a/src/core/ljcos2.cpp b/src/core/ljcos2.cpp index 6615b719e2..15d7c4651e 100755 --- a/src/core/ljcos2.cpp +++ b/src/core/ljcos2.cpp @@ -1,27 +1,27 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file ljcos2.hpp * - * Routines to calculate the lennard-jones with cosine tail energy and/or force + * Routines to calculate the lennard-jones with cosine tail energy and/or force * for a particle pair. Cosine tail is different from that in ljcos.hpp * Used for attractive tail/tail interactions in lipid bilayer calculations * \ref forces.cpp @@ -33,22 +33,21 @@ #include "communication.hpp" -int ljcos2_set_params(int part_type_a, int part_type_b, - double eps, double sig, double offset, - double w) -{ +int ljcos2_set_params(int part_type_a, int part_type_b, double eps, double sig, + double offset, double w) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; - data->LJCOS2_eps = eps; - data->LJCOS2_sig = sig; + data->LJCOS2_eps = eps; + data->LJCOS2_sig = sig; data->LJCOS2_offset = offset; - data->LJCOS2_w = w; + data->LJCOS2_w = w; /* calculate dependent parameters */ - data->LJCOS2_rchange = pow(2,1/6.)*sig; - data->LJCOS2_cut = w + data->LJCOS2_rchange; + data->LJCOS2_rchange = pow(2, 1 / 6.) * sig; + data->LJCOS2_cut = w + data->LJCOS2_rchange; /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); diff --git a/src/core/ljgen.cpp b/src/core/ljgen.cpp index f9750eb1f0..9013f684fe 100755 --- a/src/core/ljgen.cpp +++ b/src/core/ljgen.cpp @@ -38,8 +38,8 @@ #include "ljgen.hpp" int ljgen_set_params(int part_type_a, int part_type_b, double eps, double sig, - double cut, double shift, double offset, double a1, double a2, - double b1, double b2 + double cut, double shift, double offset, double a1, + double a2, double b1, double b2 #ifdef LJGEN_SOFTCORE , diff --git a/src/core/maggs.cpp b/src/core/maggs.cpp index d63547645f..255c04e029 100755 --- a/src/core/maggs.cpp +++ b/src/core/maggs.cpp @@ -1,23 +1,23 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project Copyright (C) 2010,2011 Florian Fahrenberger - Copyright (C) 2007,2008,2009,2010 + Copyright (C) 2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file maggs.cpp @@ -40,35 +40,35 @@ * I. Pasichnyk and B. Dunweg, Coulomb interaction via local * dynamics: a molecular-dynamics algorithm. J. Phys: * Condens. Matter, 16 ,p. 1399-4020, (2004). - * + * */ #include "maggs.hpp" #ifdef ELECTROSTATICS +#include "cells.hpp" +#include "communication.hpp" +#include "errorhandling.hpp" #include "ghosts.hpp" #include "global.hpp" #include "grid.hpp" -#include "integrate.hpp" #include "initialize.hpp" +#include "integrate.hpp" #include "interaction_data.hpp" -#include "particle_data.hpp" -#include "communication.hpp" #include "maggs.hpp" +#include "particle_data.hpp" #include "thermostat.hpp" -#include "cells.hpp" -#include "errorhandling.hpp" -#include #include #include #include +#include /* MPI tags for the maggs communications: */ /* Used in maggs_init() -> calc_glue_patch(). */ #define REQ_MAGGS_SPREAD 300 -#define REQ_MAGGS_EQUIL 301 +#define REQ_MAGGS_EQUIL 301 /* Factors for self-influence currection */ /* (stemming from epsilon_zero and 4*pi) */ @@ -79,99 +79,92 @@ // e_0 = 8.85418781762 * 10^-12 /* Define numbers for directions and dimensions: */ -#define SPACE_DIM 3 /* number of dimensions */ -#define NOWHERE -1 /* not a direction */ -#define NDIRS 6 /* number of directions */ -#define XPLUS 0 /* add for specific direction */ +#define SPACE_DIM 3 /* number of dimensions */ +#define NOWHERE -1 /* not a direction */ +#define NDIRS 6 /* number of directions */ +#define XPLUS 0 /* add for specific direction */ #define YPLUS 1 #define ZPLUS 2 #define ZMINUS 3 #define YMINUS 4 #define XMINUS 5 -#define OPP_DIR(dir) (5-(dir)) /* Opposite direction */ - +#define OPP_DIR(dir) (5 - (dir)) /* Opposite direction */ /* Three often used macros for looping over 3D */ -#define FOR3D(dir) for(dir=0; dir max_node_grid) max_node_grid = node_grid[d]; - + FOR3D(d) if (node_grid[d] > max_node_grid) max_node_grid = node_grid[d]; + if (maggs.prefactor == 0.) { - runtimeErrorMsg() <<"MEMD: prefactor is zero."; + runtimeErrorMsg() << "MEMD: prefactor is zero."; ret = -1; - } - else if ( (box_l[0] != box_l[1]) || (box_l[1] != box_l[2]) ) { - runtimeErrorMsg() <<"MEMD needs cubic box"; + } else if ((box_l[0] != box_l[1]) || (box_l[1] != box_l[2])) { + runtimeErrorMsg() << "MEMD needs cubic box"; ret = -1; } if (!PERIODIC(0) || !PERIODIC(1) || !PERIODIC(2)) { - runtimeErrorMsg() <<"MEMD requires periodicity 1 1 1"; + runtimeErrorMsg() << "MEMD requires periodicity 1 1 1"; ret = 1; - } - else if ( maggs.mesh%max_node_grid != 0 ) { - runtimeErrorMsg() <<"MEMD: meshsize is incompatible with number of processes"; + } else if (maggs.mesh % max_node_grid != 0) { + runtimeErrorMsg() + << "MEMD: meshsize is incompatible with number of processes"; ret = -1; } /* @@ -417,16 +429,16 @@ int maggs_sanity_checks() } */ else if (cell_structure.type != CELL_STRUCTURE_DOMDEC) { - runtimeErrorMsg() <<"MEMD requires domain-decomposition cellsystem."; + runtimeErrorMsg() << "MEMD requires domain-decomposition cellsystem."; ret = -1; } /** check if speed of light parameter makes sense */ - else if (maggs.f_mass < ( 2. / maggs.a / maggs.a ) ) { - runtimeErrorMsg() <<"MEMD: Speed of light is set too high. Increase f_mass."; - ret = -1; - } - else if (maggs.a < skin) { - runtimeErrorMsg() <<"MEMD: Skin should be smaller than MEMD mesh size."; + else if (maggs.f_mass < (2. / maggs.a / maggs.a)) { + runtimeErrorMsg() + << "MEMD: Speed of light is set too high. Increase f_mass."; + ret = -1; + } else if (maggs.a < skin) { + runtimeErrorMsg() << "MEMD: Skin should be smaller than MEMD mesh size."; ret = -1; } #ifdef EXTERNAL_FORCES @@ -476,362 +488,371 @@ void maggs_compute_dipole_correction() { /****** setup everything: ******/ /*******************************/ -int maggs_set_parameters(double prefactor, double f_mass, int mesh, int finite_epsilon_flag, double epsilon_infty) -{ - if (f_mass <=0.) { +int maggs_set_parameters(double prefactor, double f_mass, int mesh, + int finite_epsilon_flag, double epsilon_infty) { + if (f_mass <= 0.) { return -1; - } - if(mesh<0) { + } + if (mesh < 0) { return -2; } - - maggs.mesh = mesh; - maggs.finite_epsilon_flag = finite_epsilon_flag; - maggs.epsilon_infty = epsilon_infty; - maggs.prefactor = prefactor; - maggs.f_mass = f_mass; - maggs.invsqrt_f_mass = 1./sqrt(f_mass); - + + maggs.mesh = mesh; + maggs.finite_epsilon_flag = finite_epsilon_flag; + maggs.epsilon_infty = epsilon_infty; + maggs.prefactor = prefactor; + maggs.f_mass = f_mass; + maggs.invsqrt_f_mass = 1. / sqrt(f_mass); + mpi_bcast_coulomb_params(); - + return ES_OK; } - /** sets up nearest neighbors for each site in linear index */ -void maggs_setup_neighbors() -{ +void maggs_setup_neighbors() { int ix = 0; int iy = 0; int iz = 0; - + int xsize = lparams.dim[0]; int ysize = lparams.dim[1]; int zsize = lparams.dim[2]; - + int ixplus = 0; int ixminus = 0; int iyplus = 0; int iyminus = 0; int izplus = 0; int izminus = 0; - + int kount = 0; - + int kountxplus = 0; int kountxminus = 0; int kountyplus = 0; int kountyminus = 0; int kountzplus = 0; int kountzminus = 0; - - for (ix = 0; ix < xsize; ix++) - { - ixplus = ix + 1; - ixminus = ix - 1; - for(iy = 0; iy < ysize; iy ++) - { - iyplus = iy + 1; - iyminus = iy - 1; - for(iz = 0; iz < zsize; iz ++) - { - izplus = iz + 1; - izminus = iz - 1; - - kount = maggs_get_linear_index(ix, iy, iz, lparams.dim); - kountzplus = maggs_get_linear_index(ix, iy, izplus, lparams.dim); - kountzminus = maggs_get_linear_index(ix, iy, izminus, lparams.dim); - kountyplus = maggs_get_linear_index(ix, iyplus, iz, lparams.dim); - kountyminus = maggs_get_linear_index(ix, iyminus, iz, lparams.dim); - kountxplus = maggs_get_linear_index(ixplus, iy, iz, lparams.dim); - kountxminus = maggs_get_linear_index(ixminus, iy, iz, lparams.dim); - - if(ixminus < 0) neighbor[kount][XMINUS] = -1; - else neighbor[kount][XMINUS] = kountxminus; - if(ixplus >= xsize) neighbor[kount][XPLUS] = -1; - else neighbor[kount][XPLUS] = kountxplus; - - if(iyminus < 0) neighbor[kount][YMINUS] = -1; - else neighbor[kount][YMINUS] = kountyminus; - if(iyplus >= ysize) neighbor[kount][YPLUS] = -1; - else neighbor[kount][YPLUS] = kountyplus; - - if(izminus < 0) neighbor[kount][ZMINUS] = -1; - else neighbor[kount][ZMINUS] = kountzminus; - if(izplus >= zsize) neighbor[kount][ZPLUS] = -1; - else neighbor[kount][ZPLUS] = kountzplus; - } - } + + for (ix = 0; ix < xsize; ix++) { + ixplus = ix + 1; + ixminus = ix - 1; + for (iy = 0; iy < ysize; iy++) { + iyplus = iy + 1; + iyminus = iy - 1; + for (iz = 0; iz < zsize; iz++) { + izplus = iz + 1; + izminus = iz - 1; + + kount = maggs_get_linear_index(ix, iy, iz, lparams.dim); + kountzplus = maggs_get_linear_index(ix, iy, izplus, lparams.dim); + kountzminus = maggs_get_linear_index(ix, iy, izminus, lparams.dim); + kountyplus = maggs_get_linear_index(ix, iyplus, iz, lparams.dim); + kountyminus = maggs_get_linear_index(ix, iyminus, iz, lparams.dim); + kountxplus = maggs_get_linear_index(ixplus, iy, iz, lparams.dim); + kountxminus = maggs_get_linear_index(ixminus, iy, iz, lparams.dim); + + if (ixminus < 0) + neighbor[kount][XMINUS] = -1; + else + neighbor[kount][XMINUS] = kountxminus; + if (ixplus >= xsize) + neighbor[kount][XPLUS] = -1; + else + neighbor[kount][XPLUS] = kountxplus; + + if (iyminus < 0) + neighbor[kount][YMINUS] = -1; + else + neighbor[kount][YMINUS] = kountyminus; + if (iyplus >= ysize) + neighbor[kount][YPLUS] = -1; + else + neighbor[kount][YPLUS] = kountyplus; + + if (izminus < 0) + neighbor[kount][ZMINUS] = -1; + else + neighbor[kount][ZMINUS] = kountzminus; + if (izplus >= zsize) + neighbor[kount][ZPLUS] = -1; + else + neighbor[kount][ZPLUS] = kountzplus; + } } + } return; } - /** Set up lattice, calculate dimensions and lattice parameters Allocate memory for lattice sites and fields */ -void maggs_setup_local_lattice() -{ +void maggs_setup_local_lattice() { int i; int ix = 0; int iy = 0; int iz = 0; int linearindex = 0; - int xyzcube; - + int xyzcube; + xyzcube = 1; FOR3D(i) { /** inner left down grid point (global index) */ - lparams.inner_left_down[i] = (int)ceil(my_left[i]*maggs.inva); + lparams.inner_left_down[i] = (int)ceil(my_left[i] * maggs.inva); /** inner up right grid point (global index) */ - lparams.inner_up_right[i] = (int)floor(my_right[i]*maggs.inva); + lparams.inner_up_right[i] = (int)floor(my_right[i] * maggs.inva); /** correct roundof errors at boundary */ - if(my_right[i]*maggs.inva-lparams.inner_up_right[i]= lparams.halo_left_down[dim] && position < lparams.halo_upper_right[dim] ) { - on_this_node = 0; - if (this_node) - fprintf(stderr, "EPSILON! %d\n", this_node); - } else { - on_this_node = 0; - } - } - - if (on_this_node) { - /* save and return old epsilon for information purposes */ - double epsilon_before = lattice[node_index].permittivity[direction]; - /* set relative epsilon */ - lattice[node_index].permittivity[direction] = relative_epsilon; - - return epsilon_before; +double maggs_set_permittivity(int node_x, int node_y, int node_z, int direction, + double relative_epsilon) { + int node_index = maggs_get_linear_index(node_x, node_y, node_z, lparams.dim); + int dim, on_this_node = 0; + double position; + double node[3] = {(double)node_x, (double)node_y, (double)node_z}; + + FOR3D(dim) { + position = (double)node[dim] / (double)lparams.dim[dim] * box_l[dim]; + position = node[dim]; + if (position >= lparams.halo_left_down[dim] && + position < lparams.halo_upper_right[dim]) { + on_this_node = 0; + if (this_node) + fprintf(stderr, "EPSILON! %d\n", this_node); } else { - return 0.0; + on_this_node = 0; } -} + } + if (on_this_node) { + /* save and return old epsilon for information purposes */ + double epsilon_before = lattice[node_index].permittivity[direction]; + /* set relative epsilon */ + lattice[node_index].permittivity[direction] = relative_epsilon; + + return epsilon_before; + } else { + return 0.0; + } +} -int maggs_set_adaptive_flag(double scaling) -{ - maggs.adaptive_flag = 1; - maggs.scaling = scaling; - return 0; +int maggs_set_adaptive_flag(double scaling) { + maggs.adaptive_flag = 1; + maggs.scaling = scaling; + return 0; } /** set permittivity adaptively according to salt concentration - Use this very carefully, since it assumes a certain set of parameters. The length is not simulation units anymore + Use this very carefully, since it assumes a certain set of parameters. The + length is not simulation units anymore @param node_x index of the node in x direction @param node_y index of the node in y direction @param node_z index of the node in z direction */ -double maggs_set_adaptive_permittivity(int node_x, int node_y, int node_z) -{ - int node_index = maggs_get_linear_index(node_x, node_y, node_z, lparams.dim); - int dim, cell_index, on_this_node, i, np = 0; - double position; - int direction=1; - double node[3] = {(double)node_x, (double)node_y, (double)node_z}; - double concentration=0.0; - double relative_epsilon = 1.0; - Cell* cell; - Particle* p; - - FOR3D(dim) { - cell_index = neighbor[node_index][dim]; - cell = local_cells.cell[cell_index]; - p = cell->part; - np = cell->n; - - for(i=0; i= lparams.halo_left_down[dim] && position < lparams.halo_upper_right[dim] ) { - on_this_node = 0; - if (this_node) - fprintf(stderr, "EPSILON! %d\n", this_node); - } else { - on_this_node = 0; - } +double maggs_set_adaptive_permittivity(int node_x, int node_y, int node_z) { + int node_index = maggs_get_linear_index(node_x, node_y, node_z, lparams.dim); + int dim, cell_index, on_this_node, i, np = 0; + double position; + int direction = 1; + double node[3] = {(double)node_x, (double)node_y, (double)node_z}; + double concentration = 0.0; + double relative_epsilon = 1.0; + Cell *cell; + Particle *p; + + FOR3D(dim) { + cell_index = neighbor[node_index][dim]; + cell = local_cells.cell[cell_index]; + p = cell->part; + np = cell->n; + + for (i = 0; i < np; i++) { + concentration += p[i].p.q; } - - if (on_this_node) { - /* save and return old epsilon for information purposes */ - double epsilon_before = lattice[node_index].permittivity[direction]; - /* set relative epsilon */ - lattice[node_index].permittivity[direction] = relative_epsilon; - - return epsilon_before; + } + + concentration /= 0.0000035246; + relative_epsilon = 78.5 / (1.0 + 0.278 * concentration) * maggs.scaling; + + FOR3D(dim) { + position = (double)node[dim] / (double)lparams.dim[dim] * box_l[dim]; + position = node[dim]; + if (position >= lparams.halo_left_down[dim] && + position < lparams.halo_upper_right[dim]) { + on_this_node = 0; + if (this_node) + fprintf(stderr, "EPSILON! %d\n", this_node); } else { - return 0.0; + on_this_node = 0; } -} - + } + if (on_this_node) { + /* save and return old epsilon for information purposes */ + double epsilon_before = lattice[node_index].permittivity[direction]; + /* set relative epsilon */ + lattice[node_index].permittivity[direction] = relative_epsilon; + return epsilon_before; + } else { + return 0.0; + } +} /*****************************************/ /****** Surface patch communication ******/ @@ -843,130 +864,140 @@ double maggs_set_adaptive_permittivity(int node_x, int node_y, int node_z) @param dim Dimension in which to communicate @param e_equil Flag if field is already equilibated */ -void maggs_exchange_surface_patch(double *field, int dim, int e_equil) -{ +void maggs_exchange_surface_patch(double *field, int dim, int e_equil) { static int init = 1; - static MPI_Datatype xyPlane,xzPlane,yzPlane; + static MPI_Datatype xyPlane, xzPlane, yzPlane; static MPI_Datatype xzPlane2D, xyPlane2D, yzPlane2D; /* int coord[2]; */ int l, s_dir, r_dir; /* int pos=0; */ MPI_Status status[2]; - MPI_Request request[]={MPI_REQUEST_NULL, MPI_REQUEST_NULL}; + MPI_Request request[] = {MPI_REQUEST_NULL, MPI_REQUEST_NULL}; int offset, doffset, skip, stride, nblocks; /** surface_patch */ - static t_surf_patch surface_patch[6]; - - if(init) { + static t_surf_patch surface_patch[6]; + + if (init) { MPI_Datatype xz_plaq, oneslice; - + maggs_calc_surface_patches(surface_patch); - maggs_prepare_surface_planes(dim, &xyPlane, &xzPlane, &yzPlane, surface_patch); - - MPI_Type_vector(surface_patch[0].stride, 2, 3, MPI_DOUBLE,&yzPlane2D); + maggs_prepare_surface_planes(dim, &xyPlane, &xzPlane, &yzPlane, + surface_patch); + + MPI_Type_vector(surface_patch[0].stride, 2, 3, MPI_DOUBLE, &yzPlane2D); MPI_Type_commit(&yzPlane2D); - + /* create data type for xz plaquette */ - MPI_Type_create_hvector(2,1*sizeof(double),2*sizeof(double), MPI_BYTE, &xz_plaq); + MPI_Type_create_hvector(2, 1 * sizeof(double), 2 * sizeof(double), MPI_BYTE, + &xz_plaq); /* create data type for a 1D section */ - MPI_Type_contiguous(surface_patch[2].stride, xz_plaq, &oneslice); + MPI_Type_contiguous(surface_patch[2].stride, xz_plaq, &oneslice); /* create data type for a 2D xz plane */ - MPI_Type_create_hvector(surface_patch[2].nblocks, 1, dim*surface_patch[2].skip*sizeof(double), oneslice, &xzPlane2D); - MPI_Type_commit(&xzPlane2D); + MPI_Type_create_hvector(surface_patch[2].nblocks, 1, + dim * surface_patch[2].skip * sizeof(double), + oneslice, &xzPlane2D); + MPI_Type_commit(&xzPlane2D); /* create data type for a 2D xy plane */ - MPI_Type_vector(surface_patch[4].nblocks, 2, dim*surface_patch[4].skip, MPI_DOUBLE, &xyPlane2D); - MPI_Type_commit(&xyPlane2D); - + MPI_Type_vector(surface_patch[4].nblocks, 2, dim * surface_patch[4].skip, + MPI_DOUBLE, &xyPlane2D); + MPI_Type_commit(&xyPlane2D); + init = 0; } - - + /** direction loop */ - for(s_dir=0; s_dir < 6; s_dir++) { + for (s_dir = 0; s_dir < 6; s_dir++) { offset = dim * surface_patch[s_dir].offset; - doffset= dim * surface_patch[s_dir].doffset; - - if(s_dir%2==0) r_dir = s_dir+1; - else r_dir = s_dir-1; + doffset = dim * surface_patch[s_dir].doffset; + + if (s_dir % 2 == 0) + r_dir = s_dir + 1; + else + r_dir = s_dir - 1; /** pack send halo-plane data */ - if(node_neighbors[s_dir] != this_node) { + if (node_neighbors[s_dir] != this_node) { /** communication */ - switch(s_dir) { - case 0 : - case 1 : - if(e_equil || dim == 1) { -/* MPI_Sendrecv( sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm, status ) - - if (rank%2) { - MPI_Send(&data, 1, MPI_INT, next, 42, comm); - MPI_Recv(&data, 1, MPI_INT, prev, 42, comm, 0); - } else { - MPI_Recv(&data, 1, MPI_INT, prev, 42, comm, 0); - MPI_Send(&data, 1, MPI_INT, next, 42, comm); - } - - MPI_Sendrecv(&send_data, 1, MPI_FLOAT, next, 42, &recv_data, 1, MPI_FLOAT, prev, 42, comm, 0); - MPI_Sendrecv_replace(&data, 1, MPI_FLOAT, next, 42, prev, 42, comm, 0); - */ - MPI_Irecv (&field[doffset],1,yzPlane,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset],1,yzPlane,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - else { - MPI_Irecv (&field[doffset+1],1,yzPlane2D,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset+1],1,yzPlane2D,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - - MPI_Waitall(2,request,status); - break; - case 2 : - case 3 : - if(e_equil || dim == 1) { - MPI_Irecv (&field[doffset],1,xzPlane,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset],1,xzPlane,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - else { - MPI_Irecv (&field[doffset],1,xzPlane2D,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset],1,xzPlane2D,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - MPI_Waitall(2,request,status); - break; - case 4 : - case 5 : - if(e_equil || dim == 1) { - MPI_Irecv (&field[doffset],1,xyPlane,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset],1,xyPlane,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - else { - MPI_Irecv (&field[doffset],1,xyPlane2D,node_neighbors[s_dir],REQ_MAGGS_SPREAD,comm_cart,&request[0]); - MPI_Isend(&field[offset],1,xyPlane2D,node_neighbors[r_dir],REQ_MAGGS_SPREAD,comm_cart,&request[1]); - } - MPI_Waitall(2,request,status); - break; + switch (s_dir) { + case 0: + case 1: + if (e_equil || dim == 1) { + /* MPI_Sendrecv( sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, + recvcount, recvtype, source, recvtag, comm, status ) + + if (rank%2) { + MPI_Send(&data, 1, MPI_INT, next, 42, comm); + MPI_Recv(&data, 1, MPI_INT, prev, 42, comm, 0); + } else { + MPI_Recv(&data, 1, MPI_INT, prev, 42, comm, 0); + MPI_Send(&data, 1, MPI_INT, next, 42, comm); + } + + MPI_Sendrecv(&send_data, 1, MPI_FLOAT, next, 42, &recv_data, 1, + MPI_FLOAT, prev, 42, comm, 0); + MPI_Sendrecv_replace(&data, 1, MPI_FLOAT, next, 42, prev, 42, comm, + 0); + */ + MPI_Irecv(&field[doffset], 1, yzPlane, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset], 1, yzPlane, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } else { + MPI_Irecv(&field[doffset + 1], 1, yzPlane2D, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset + 1], 1, yzPlane2D, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } + + MPI_Waitall(2, request, status); + break; + case 2: + case 3: + if (e_equil || dim == 1) { + MPI_Irecv(&field[doffset], 1, xzPlane, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset], 1, xzPlane, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } else { + MPI_Irecv(&field[doffset], 1, xzPlane2D, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset], 1, xzPlane2D, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } + MPI_Waitall(2, request, status); + break; + case 4: + case 5: + if (e_equil || dim == 1) { + MPI_Irecv(&field[doffset], 1, xyPlane, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset], 1, xyPlane, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } else { + MPI_Irecv(&field[doffset], 1, xyPlane2D, node_neighbors[s_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[0]); + MPI_Isend(&field[offset], 1, xyPlane2D, node_neighbors[r_dir], + REQ_MAGGS_SPREAD, comm_cart, &request[1]); + } + MPI_Waitall(2, request, status); + break; } } else { /** copy locally */ - skip = dim * surface_patch[s_dir].skip; - stride = dim * surface_patch[s_dir].stride * sizeof(double); + skip = dim * surface_patch[s_dir].skip; + stride = dim * surface_patch[s_dir].stride * sizeof(double); nblocks = surface_patch[s_dir].nblocks; - - for(l=0; l 0) - { - maggs.alpha[i][j] += cos(nomx + nomy + nomz) / sxyz; - } - } - } - } - /* invasq is needed for the calculation of forces */ - maggs.alpha[i][j] = invasq * prefac * maggs.alpha[i][j]; - } + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + maggs.alpha[i][j] = 0.; + for (px = 0; px < maggs.mesh; ++px) { + sx = sin(factor * px); + sx = sx * sx; + nomx = 2. * factor * px * (n[i][0] - n[j][0]); + for (py = 0; py < maggs.mesh; ++py) { + sy = sin(factor * py); + sy = sy * sy; + nomy = 2. * factor * py * (n[i][1] - n[j][1]); + sxy = sx + sy; + for (pz = 0; pz < maggs.mesh; ++pz) { + sz = sin(factor * pz); + sz = sz * sz; + nomz = 2. * factor * pz * (n[i][2] - n[j][2]); + sxyz = sxy + sz; + sxyz *= 4.; + if (sxyz > 0) { + maggs.alpha[i][j] += cos(nomx + nomy + nomz) / sxyz; + } + } + } + } + /* invasq is needed for the calculation of forces */ + maggs.alpha[i][j] = invasq * prefac * maggs.alpha[i][j]; } - + } } /** For energy minimization: @return maximum of curl(E) from all sites. May also be used to verify constraint surface condition. */ -double maggs_check_curl_E() -{ +double maggs_check_curl_E() { int i, ix, iy, iz; double curl, maxcurl, gmaxcurl; - int* anchor_neighb; - + int *anchor_neighb; + maxcurl = 0.; - + FORALL_INNER_SITES(ix, iy, iz) { - i = maggs_get_linear_index(ix, iy, iz, lparams.dim); + i = maggs_get_linear_index(ix, iy, iz, lparams.dim); anchor_neighb = neighbor[i]; - curl = Dfield[3*i] + Dfield[3*anchor_neighb[0]+1] - - Dfield[3*anchor_neighb[1]] - Dfield[3*i+1]; + curl = Dfield[3 * i] + Dfield[3 * anchor_neighb[0] + 1] - + Dfield[3 * anchor_neighb[1]] - Dfield[3 * i + 1]; curl *= maggs.inva; - if(fabs(curl)>maxcurl) maxcurl = fabs(curl); - curl = Dfield[3*i+2] + Dfield[3*anchor_neighb[2]] - - Dfield[3*anchor_neighb[0]+2] - Dfield[3*i]; + if (fabs(curl) > maxcurl) + maxcurl = fabs(curl); + curl = Dfield[3 * i + 2] + Dfield[3 * anchor_neighb[2]] - + Dfield[3 * anchor_neighb[0] + 2] - Dfield[3 * i]; curl *= maggs.inva; - if(fabs(curl)>maxcurl) maxcurl = fabs(curl); - curl = Dfield[3*i+1] + Dfield[3*anchor_neighb[1]+2] - - Dfield[3*anchor_neighb[2]+1] - Dfield[3*i+2]; + if (fabs(curl) > maxcurl) + maxcurl = fabs(curl); + curl = Dfield[3 * i + 1] + Dfield[3 * anchor_neighb[1] + 2] - + Dfield[3 * anchor_neighb[2] + 1] - Dfield[3 * i + 2]; curl *= maggs.inva; - if(fabs(curl)>maxcurl) maxcurl = fabs(curl); + if (fabs(curl) > maxcurl) + maxcurl = fabs(curl); } - MPI_Allreduce(&maxcurl,&gmaxcurl,1,MPI_DOUBLE,MPI_MAX,comm_cart); + MPI_Allreduce(&maxcurl, &gmaxcurl, 1, MPI_DOUBLE, MPI_MAX, comm_cart); return gmaxcurl; } @@ -1262,92 +1282,90 @@ double maggs_check_curl_E() @param i index of the current lattice site @param n coordinate, is the normal direction to the plaquette */ -void maggs_perform_rot_move_inplane(int i, int n) -{ +void maggs_perform_rot_move_inplane(int i, int n) { int mue, nue; - int * anchor_neighb; + int *anchor_neighb; double delta; - double ROUND_ERR = 0.01*ROUND_ERROR_PREC; - - mue = 0; nue = 0; - - switch(n) { - case 0 : + double ROUND_ERR = 0.01 * ROUND_ERROR_PREC; + + mue = 0; + nue = 0; + + switch (n) { + case 0: mue = 1; nue = 2; break; - - case 1 : + + case 1: mue = 2; nue = 0; break; - case 2 : + case 2: mue = 0; nue = 1; break; } - + anchor_neighb = &neighbor[i][0]; - - delta = Dfield[3*i+mue] + Dfield[3*anchor_neighb[mue]+nue] - - Dfield[3*anchor_neighb[nue]+mue] - Dfield[3*i+nue]; - if(fabs(delta)>=ROUND_ERR) { - delta = -delta/4.; + + delta = Dfield[3 * i + mue] + Dfield[3 * anchor_neighb[mue] + nue] - + Dfield[3 * anchor_neighb[nue] + mue] - Dfield[3 * i + nue]; + if (fabs(delta) >= ROUND_ERR) { + delta = -delta / 4.; maggs_update_plaquette(mue, nue, anchor_neighb, i, delta); } } - /** For energy minimization: Relax B-fields in all directions.*/ -void maggs_minimize_transverse_field() -{ +void maggs_minimize_transverse_field() { int k, l, m; int i, d; int ind_i, ind_j; - int size[2]={0,0}; + int size[2] = {0, 0}; int index = -1; /* force allocation error */ - + FOR3D(d) { - switch(d) { - case 0 : + switch (d) { + case 0: size[0] = lparams.size[2]; size[1] = lparams.size[1]; break; - case 1 : + case 1: size[0] = lparams.size[2]; size[1] = lparams.size[0]; break; - case 2 : + case 2: size[0] = lparams.size[1]; size[1] = lparams.size[0]; break; } - for(i=0;i<2;i++) { + for (i = 0; i < 2; i++) { /* at first even sites (i==0) then odd */ - for(k=1;k<=lparams.size[d];k++) { - /* update every plane in direction d */ - ind_i=0; - for(l=0; l<=size[1]; l++){ - ind_j=0; - for(m=0;m<=size[0]; m++) { - switch(d) { - case 0 : - index=maggs_get_linear_index(k,l,m,lparams.dim); - break; - case 1 : - index=maggs_get_linear_index(l,k,m,lparams.dim); - break; - case 2 : - index=maggs_get_linear_index(l,m,k,lparams.dim); - break; - } - if((ind_i+ind_j)%2==i) - maggs_perform_rot_move_inplane(index, d); - ind_j++; - } - ind_i++; - } + for (k = 1; k <= lparams.size[d]; k++) { + /* update every plane in direction d */ + ind_i = 0; + for (l = 0; l <= size[1]; l++) { + ind_j = 0; + for (m = 0; m <= size[0]; m++) { + switch (d) { + case 0: + index = maggs_get_linear_index(k, l, m, lparams.dim); + break; + case 1: + index = maggs_get_linear_index(l, k, m, lparams.dim); + break; + case 2: + index = maggs_get_linear_index(l, m, k, lparams.dim); + break; + } + if ((ind_i + ind_j) % 2 == i) + maggs_perform_rot_move_inplane(index, d); + ind_j++; + } + ind_i++; + } } /* update boundaries - update halo regions */ maggs_exchange_surface_patch(Dfield, 3, 0); @@ -1355,17 +1373,15 @@ void maggs_minimize_transverse_field() } } - /** calculates initial electric field configuration. currently uses simple and slow method of plaquettes and links. energy minimization takes up lots of time. */ -void maggs_calc_init_e_field() -{ +void maggs_calc_init_e_field() { double localqy, localqz; double qplane, qline; - int i, k, ix, iy, iz; + int i, k, ix, iy, iz; int index = 0; - double invasq, tmp_field=0.0; + double invasq, tmp_field = 0.0; double sqrE, gsqrE, gavgEx, gavgEy, gavgEz; double qz, qy, qx, avgEx, avgEy, avgEz; double Eall[SPACE_DIM], gEall[SPACE_DIM]; @@ -1373,223 +1389,246 @@ void maggs_calc_init_e_field() MPI_Status status; MPI_Comm zplane, yline; int color, rank, dim; - - MAGGS_TRACE(fprintf(stderr,"%d:Initialize field\n",this_node)); - - invasq = maggs.inva*maggs.inva; - + + MAGGS_TRACE(fprintf(stderr, "%d:Initialize field\n", this_node)); + + invasq = maggs.inva * maggs.inva; + /* sort particles for the calculation of initial charge distribution */ - MAGGS_TRACE(fprintf(stderr,"%d:Sorting particles...\n",this_node)); - + MAGGS_TRACE(fprintf(stderr, "%d:Sorting particles...\n", this_node)); + cells_resort_particles(CELL_GLOBAL_EXCHANGE); /* fprintf(stderr, "done\n"); */ maggs_distribute_particle_charges(); - - dim = node_grid[1]*node_grid[0]; + + dim = node_grid[1] * node_grid[0]; color = node_pos[2]; - rank = this_node%dim; + rank = this_node % dim; MPI_Comm_split(comm_cart, color, rank, &zplane); color = node_pos[1]; - rank = rank%node_grid[0]; + rank = rank % node_grid[0]; MPI_Comm_split(zplane, color, rank, &yline); - + /* calculate initial solution of Poisson equation */ - + /* CAUTION: the indexing of the neighbor nodes in Espresso * starts from x left neighbor node */ - + /* get process coordinates */ - if(node_pos[2]!= 0) { - MPI_Recv(&tmp_field, 1, MPI_DOUBLE, node_neighbors[4], REQ_MAGGS_EQUIL, comm_cart, &status); - for(iy=lparams.inner_left_down[1];iy= 0.01*ROUND_ERROR_PREC) { */ - for(iy=lparams.inner_left_down[1];iy=lparams.inner_up_right[2]-1) { - if (node_pos[2]1) { - MPI_Send(&Dfield[3*index+ZPLUS], 1, MPI_DOUBLE, node_neighbors[5], REQ_MAGGS_EQUIL, comm_cart); - } + if (iz >= lparams.inner_up_right[2] - 1) { + if (node_pos[2] < node_grid[2] - 1) { + if (node_grid[2] > 1) { + MPI_Send(&Dfield[3 * index + ZPLUS], 1, MPI_DOUBLE, node_neighbors[5], + REQ_MAGGS_EQUIL, comm_cart); + } + } else if (fabs(Dfield[3 * index + ZPLUS]) > 100. * ROUND_ERROR_PREC) { + fprintf(stderr, "%d: Error in the calculation of Ez(%d,%d,%d)=%f!!\n", + this_node, lattice[index].r[0], lattice[index].r[1], + lattice[index].r[2], Dfield[3 * index + ZPLUS]); + fflush(stderr); } - else - if (fabs(Dfield[3*index+ZPLUS]) > 100.*ROUND_ERROR_PREC) { - fprintf(stderr, "%d: Error in the calculation of Ez(%d,%d,%d)=%f!!\n", - this_node,lattice[index].r[0], lattice[index].r[1], lattice[index].r[2], - Dfield[3*index+ZPLUS]); - fflush(stderr); - } } - if(node_pos[1]!= 0) { - MPI_Recv(&tmp_field, 1, MPI_DOUBLE, node_neighbors[2], REQ_MAGGS_EQUIL, comm_cart, &status); - for(ix=lparams.inner_left_down[0];ix=ROUND_ERROR_PREC) { */ - for(ix=lparams.inner_left_down[0];ix=lparams.inner_up_right[1]-1) { - if(node_pos[1] < node_grid[1]-1) { - if (node_grid[1]>1) - MPI_Send(&Dfield[3*index+YPLUS], 1, MPI_DOUBLE, node_neighbors[3], REQ_MAGGS_EQUIL, comm_cart); - } - else - if (fabs(Dfield[3*index+YPLUS]) > 100.*ROUND_ERROR_PREC) - fprintf(stderr, "%d: Error in the calculation of Ey(%d,%d,%d)=%f!!\n", - this_node, lattice[index].r[0], lattice[index].r[1], lattice[index].r[2], - Dfield[3*index+YPLUS]); + + if (iy >= lparams.inner_up_right[1] - 1) { + if (node_pos[1] < node_grid[1] - 1) { + if (node_grid[1] > 1) + MPI_Send(&Dfield[3 * index + YPLUS], 1, MPI_DOUBLE, + node_neighbors[3], REQ_MAGGS_EQUIL, comm_cart); + } else if (fabs(Dfield[3 * index + YPLUS]) > 100. * ROUND_ERROR_PREC) + fprintf(stderr, "%d: Error in the calculation of Ey(%d,%d,%d)=%f!!\n", + this_node, lattice[index].r[0], lattice[index].r[1], + lattice[index].r[2], Dfield[3 * index + YPLUS]); } - - if(node_pos[0]!= 0) { - MPI_Recv(&tmp_field, 1, MPI_DOUBLE, node_neighbors[0], REQ_MAGGS_EQUIL, comm_cart, &status); - index = maggs_get_linear_index(lparams.inner_left_down[0], iy, iz, lparams.dim); - Dfield[3*neighbor[index][XMINUS]+XPLUS] = tmp_field; + + if (node_pos[0] != 0) { + MPI_Recv(&tmp_field, 1, MPI_DOUBLE, node_neighbors[0], REQ_MAGGS_EQUIL, + comm_cart, &status); + index = maggs_get_linear_index(lparams.inner_left_down[0], iy, iz, + lparams.dim); + Dfield[3 * neighbor[index][XMINUS] + XPLUS] = tmp_field; } - - for(ix=lparams.inner_left_down[0];ix=lparams.inner_up_right[0]-1) { - if(node_pos[0] < node_grid[0]-1) { - if(node_grid[0]>1) - MPI_Send(&Dfield[3*index+XPLUS], 1, MPI_DOUBLE, node_neighbors[1], REQ_MAGGS_EQUIL, comm_cart); - } - else - if (fabs(Dfield[3*index+XPLUS]) > 100.*ROUND_ERROR_PREC) - fprintf(stderr, "%d: Error in the calculation of Ex(%d,%d,%d)=%f!!\n", - this_node, lattice[index].r[0], lattice[index].r[1], lattice[index].r[2], - Dfield[3*index+XPLUS]); + + if (ix >= lparams.inner_up_right[0] - 1) { + if (node_pos[0] < node_grid[0] - 1) { + if (node_grid[0] > 1) + MPI_Send(&Dfield[3 * index + XPLUS], 1, MPI_DOUBLE, + node_neighbors[1], REQ_MAGGS_EQUIL, comm_cart); + } else if (fabs(Dfield[3 * index + XPLUS]) > 100. * ROUND_ERROR_PREC) + fprintf(stderr, "%d: Error in the calculation of Ex(%d,%d,%d)=%f!!\n", + this_node, lattice[index].r[0], lattice[index].r[1], + lattice[index].r[2], Dfield[3 * index + XPLUS]); } - } /*** loop over iy */ + } /*** loop over iy */ } - + /* exchange halo-surfaces */ - maggs_exchange_surface_patch(Dfield, 3, 1); - + maggs_exchange_surface_patch(Dfield, 3, 1); + avgEz = 0.; - for(iz=lparams.inner_left_down[2];iz1000000.*ROUND_ERROR_PREC); - - - - - - - - - + + } while (fabs(maxcurl) > 1000000. * ROUND_ERROR_PREC); + /* exchange halo-surfaces */ - + FOR3D(k) Eall[k] = 0.; FORALL_INNER_SITES(ix, iy, iz) { i = maggs_get_linear_index(ix, iy, iz, lparams.dim); - FOR3D(k) { - Eall[k] += Dfield[3*i+k]; - } + FOR3D(k) { Eall[k] += Dfield[3 * i + k]; } } - - MPI_Allreduce(Eall,gEall,3,MPI_DOUBLE,MPI_SUM,comm_cart); - - FOR3D(k) gEall[k] /= (n_nodes*lparams.size[0]*lparams.size[1]*lparams.size[2]); - + + MPI_Allreduce(Eall, gEall, 3, MPI_DOUBLE, MPI_SUM, comm_cart); + + FOR3D(k) + gEall[k] /= (n_nodes * lparams.size[0] * lparams.size[1] * lparams.size[2]); + FORALL_INNER_SITES(ix, iy, iz) { i = maggs_get_linear_index(ix, iy, iz, lparams.dim); - FOR3D(k) Dfield[3*i+k] -= gEall[k]; + FOR3D(k) Dfield[3 * i + k] -= gEall[k]; } /* exchange whole glue-patch region */ maggs_exchange_surface_patch(Dfield, 3, 0); - if(!this_node) { - MAGGS_TRACE(fprintf(stderr, "Ex = %16.12e, Ey = %15.12e, Ez = %15.12e\n", gEall[0], gEall[1], gEall[2])); + if (!this_node) { + MAGGS_TRACE(fprintf(stderr, "Ex = %16.12e, Ey = %15.12e, Ez = %15.12e\n", + gEall[0], gEall[1], gEall[2])); } } - - - - - - - /*********************************************/ /****** calculate currents and E-fields ******/ /*********************************************/ /** calculate the charge flux in direction "dir". @param q charge of the moving particle - @param help the relative position in the cube to the opposite of left down front lattice site. + @param help the relative position in the cube to the opposite of left down + front lattice site. @param flux flux variable to write into @param dir direction in which to calculate the flux */ -void maggs_calc_charge_fluxes_1D(double q, double *help, double *flux, int dir) -{ +void maggs_calc_charge_fluxes_1D(double q, double *help, double *flux, + int dir) { /* at the moment works only for linear interpolation */ int index, dir1, dir2; - int l,m; + int l, m; double q_scaled; - - q_scaled = q * maggs.pref1*maggs.inva; + + q_scaled = q * maggs.pref1 * maggs.inva; index = 0; - - maggs_calc_directions(dir, &dir1, &dir2); - - for(l=0;l<2;l++){ /* jumps from dir2- to dir2+ */ - for(m=0;m<2;m++){ /* jumps from dir1- to dir1+ */ - - flux[index] = q_scaled * help[dir1]*help[dir2]; + + maggs_calc_directions(dir, &dir1, &dir2); + + for (l = 0; l < 2; l++) { /* jumps from dir2- to dir2+ */ + for (m = 0; m < 2; m++) { /* jumps from dir1- to dir1+ */ + + flux[index] = q_scaled * help[dir1] * help[dir2]; index++; - + help[dir1] = 1. - help[dir1]; } - help[dir2] = 1. - help[dir2]; + help[dir2] = 1. - help[dir2]; } } @@ -1703,36 +1730,43 @@ void maggs_calc_charge_fluxes_1D(double q, double *help, double *flux, int dir) @param t_step time step @param identity particle ID */ -int maggs_check_intersect_1D(double delta, double r_new, int dir, int first, double *t_step, int identity) -{ +int maggs_check_intersect_1D(double delta, double r_new, int dir, int first, + double *t_step, int identity) { int candidateplane = -1; /* force alloc error */ - int f_crossing; + int f_crossing; double r_old, temp; double ZERO = 0.0; - double ONE = 1.0; - + double ONE = 1.0; + f_crossing = 0; r_old = r_new - delta; - f_crossing = f_crossing||(r_old>=ONE||r_old= ONE || r_old < ZERO); + + if (dir == 2) + temp = 1.; + else + temp = 0.5; + + if (f_crossing) { MAGGS_TRACE( - fprintf(stderr, "Cube crossing in dir %d for particle %d at time = %f:\n", dir, identity, sim_time); - fprintf(stderr," rold[%d]=%f, rnew[%d]=%f\n", dir, (first+r_old-1.)*maggs.a, - dir, (first+r_new-1.)*maggs.a); - fflush(stderr); - ); - - if(r_old >= ONE) candidateplane = ONE; - if(r_old < ZERO) candidateplane = ZERO; - + fprintf(stderr, + "Cube crossing in dir %d for particle %d at time = %f:\n", dir, + identity, sim_time); + fprintf(stderr, " rold[%d]=%f, rnew[%d]=%f\n", dir, + (first + r_old - 1.) * maggs.a, dir, + (first + r_new - 1.) * maggs.a); + fflush(stderr);); + + if (r_old >= ONE) + candidateplane = ONE; + if (r_old < ZERO) + candidateplane = ZERO; + /****** Update time step *********************/ - *t_step = temp * fabs((candidateplane-r_new)/delta); + *t_step = temp * fabs((candidateplane - r_new) / delta); } /* end if crossing */ - else *t_step = temp; + else + *t_step = temp; return f_crossing; } @@ -1743,135 +1777,153 @@ int maggs_check_intersect_1D(double delta, double r_new, int dir, int first, dou @param v speed of particle @param dir first direction of flux calculation */ -void maggs_calc_e_field_on_link_1D(int index, double *flux, double v, int dir) -{ +void maggs_calc_e_field_on_link_1D(int index, double *flux, double v, int dir) { int l, m, ind_flux, dir1, dir2; int temp_ind; int help_index[2]; - int* anchor_neighb; - t_site* anchor_site; - + int *anchor_neighb; + t_site *anchor_site; + maggs_calc_directions(dir, &dir1, &dir2); - - anchor_neighb = &neighbor[index][0]; + + anchor_neighb = &neighbor[index][0]; anchor_site = &lattice[index]; - + temp_ind = anchor_neighb[dir1]; - if(temp_ind == NOWHERE) help_index[0] = lparams.volume; + if (temp_ind == NOWHERE) + help_index[0] = lparams.volume; else - help_index[0] = maggs_get_offset(lattice[temp_ind].r[dir1], anchor_site->r[dir1], dir1, lparams.dim); + help_index[0] = maggs_get_offset(lattice[temp_ind].r[dir1], + anchor_site->r[dir1], dir1, lparams.dim); temp_ind = anchor_neighb[dir2]; - if(temp_ind == NOWHERE) help_index[1] = lparams.volume; + if (temp_ind == NOWHERE) + help_index[1] = lparams.volume; else - help_index[1] = maggs_get_offset(lattice[temp_ind].r[dir2], anchor_site->r[dir2], dir2, lparams.dim); - - + help_index[1] = maggs_get_offset(lattice[temp_ind].r[dir2], + anchor_site->r[dir2], dir2, lparams.dim); + ind_flux = 0; - for(l=0;l<2;l++){ /* jumps from dir2- to dir2+ */ - for(m=0;m<2;m++){ /* jumps from dir1- to dir1+ */ - - if(index < lparams.volume){ - Dfield[3*index+dir] -= flux[ind_flux] * v; + for (l = 0; l < 2; l++) { /* jumps from dir2- to dir2+ */ + for (m = 0; m < 2; m++) { /* jumps from dir1- to dir1+ */ + + if (index < lparams.volume) { + Dfield[3 * index + dir] -= flux[ind_flux] * v; } - - ind_flux++; - - index+=help_index[0]; - help_index[0]=-help_index[0]; + + ind_flux++; + + index += help_index[0]; + help_index[0] = -help_index[0]; } - index+=help_index[1]; - help_index[1]=-help_index[1]; + index += help_index[1]; + help_index[1] = -help_index[1]; } } - /** loop over all cells and call charge current functions @param p Particle pointer @param ghost_cell flag if cell is ghost cell */ -void maggs_add_current_on_segment(Particle *p, int ghost_cell) -{ +void maggs_add_current_on_segment(Particle *p, int ghost_cell) { int d; int icoord, dir; int lat_index = -1; /* force alloc error */ int first[SPACE_DIM]; int f_crossing, flag_update_flux; - t_dvector r_temp; + t_dvector r_temp; double delta; double flux[4], v; double v_inva[SPACE_DIM], v_invasq[SPACE_DIM]; double pos[SPACE_DIM], help[3]; double t_step; - + FOR3D(d) { - pos[d] = (p->r.p[d] - lparams.left_down_position[d])* maggs.inva; - first[d] = (int) floor(pos[d]); - r_temp[d] = pos[d] - first[d]; /* it is the updated coord (we have to go back) */ - help[d] = 1. - r_temp[d]; - v_inva[d] = maggs.inva * p->m.v[d]; + pos[d] = (p->r.p[d] - lparams.left_down_position[d]) * maggs.inva; + first[d] = (int)floor(pos[d]); + r_temp[d] = + pos[d] - first[d]; /* it is the updated coord (we have to go back) */ + help[d] = 1. - r_temp[d]; + v_inva[d] = maggs.inva * p->m.v[d]; v_invasq[d] = maggs.inva * v_inva[d]; } - + flag_update_flux = 1; - if(ghost_cell) { - FOR3D(d) if(first[d]= lparams.halo_upper_right[d]) - {flag_update_flux = 0;break;} + if (ghost_cell) { + FOR3D(d) + if (first[d] < lparams.halo_left_down[d] || + first[d] >= lparams.halo_upper_right[d]) { + flag_update_flux = 0; + break; + } } - - if(flag_update_flux) { - lat_index = maggs_get_linear_index(first[0], first[1], first[2], lparams.dim); + + if (flag_update_flux) { + lat_index = + maggs_get_linear_index(first[0], first[1], first[2], lparams.dim); } - + /* loop coordinates in order x->y->z->y->x */ - for(dir=0; dir<5; dir++) { + for (dir = 0; dir < 5; dir++) { icoord = dir; - if(dir>2) icoord = dir%2; - if(icoord == 2) delta = v_inva[icoord]; - else delta = 0.5 * v_inva[icoord]; - - f_crossing = maggs_check_intersect_1D(delta, r_temp[icoord], icoord, first[icoord], &t_step, p->p.identity); - + if (dir > 2) + icoord = dir % 2; + if (icoord == 2) + delta = v_inva[icoord]; + else + delta = 0.5 * v_inva[icoord]; + + f_crossing = maggs_check_intersect_1D( + delta, r_temp[icoord], icoord, first[icoord], &t_step, p->p.identity); + /* calculate flux */ - if(flag_update_flux) { + if (flag_update_flux) { maggs_calc_charge_fluxes_1D(p->p.q, help, flux, icoord); - + v = t_step * v_invasq[icoord]; maggs_calc_e_field_on_link_1D(lat_index, flux, v, icoord); } - - if(f_crossing) { - if(delta > 0.) { - first[icoord]--; - r_temp[icoord] += 1.; - } - else { - first[icoord]++; - r_temp[icoord] -= 1.; + + if (f_crossing) { + if (delta > 0.) { + first[icoord]--; + r_temp[icoord] += 1.; + } else { + first[icoord]++; + r_temp[icoord] -= 1.; } - if(icoord == 2) t_step = 1. - t_step; - else t_step = 0.5 - t_step; - - if(ghost_cell){ - if(flag_update_flux) { - if(first[icoord]= lparams.halo_upper_right[icoord]) - {flag_update_flux = 0;} - } - else { - flag_update_flux = 1; - FOR3D(d) if(first[d]= lparams.halo_upper_right[d]) - {flag_update_flux = 0;break;} - if(flag_update_flux) maggs_calc_charge_fluxes_1D(p->p.q, help, flux, icoord); - } + if (icoord == 2) + t_step = 1. - t_step; + else + t_step = 0.5 - t_step; + + if (ghost_cell) { + if (flag_update_flux) { + if (first[icoord] < lparams.halo_left_down[icoord] || + first[icoord] >= lparams.halo_upper_right[icoord]) { + flag_update_flux = 0; + } + } else { + flag_update_flux = 1; + FOR3D(d) + if (first[d] < lparams.halo_left_down[d] || + first[d] >= lparams.halo_upper_right[d]) { + flag_update_flux = 0; + break; + } + if (flag_update_flux) + maggs_calc_charge_fluxes_1D(p->p.q, help, flux, icoord); + } } - - if(flag_update_flux) { - v = t_step * v_invasq[icoord]; - lat_index = maggs_get_linear_index(first[0], first[1], first[2], lparams.dim); - maggs_calc_e_field_on_link_1D(lat_index, flux, v, icoord); + + if (flag_update_flux) { + v = t_step * v_invasq[icoord]; + lat_index = + maggs_get_linear_index(first[0], first[1], first[2], lparams.dim); + maggs_calc_e_field_on_link_1D(lat_index, flux, v, icoord); } } r_temp[icoord] -= delta; - help[icoord] = 1. - r_temp[icoord]; + help[icoord] = 1. - r_temp[icoord]; } } @@ -1917,37 +1969,40 @@ void maggs_couple_current_to_Dfield() { /****** calculate B-fields and forces ******/ /*******************************************/ -/** propagate the B-field via \f$\frac{\partial}{\partial t}{B} = \nabla\times D\f$ (and prefactor) +/** propagate the B-field via \f$\frac{\partial}{\partial t}{B} = \nabla\times + D\f$ (and prefactor) CAREFUL: Usually this function is called twice, with dt/2 each time to ensure a time reversible integration scheme! @param dt time step for update. Should be half the MD time step */ -void maggs_propagate_B_field(double dt) -{ +void maggs_propagate_B_field(double dt) { int x, y, z, i, offset, index; int xoffset, yoffset; - double help = dt*maggs.invsqrt_f_mass; - /* B(t+h/2) = B(t-h/2) + h*curlE(t) */ - - offset = maggs_get_linear_index(1,1,1, lparams.dim); + double help = dt * maggs.invsqrt_f_mass; + /* B(t+h/2) = B(t-h/2) + h*curlE(t) */ + + offset = maggs_get_linear_index(1, 1, 1, lparams.dim); yoffset = lparams.dim[2]; - xoffset = 2*lparams.dim[2]; - - for(x=0;xf.f; + double local_rho[8]; + double local_permittivity[12]; + double local_D_field[12]; + double *force = p->f.f; - // calculate position in cell, normalized to lattice size: - FOR3D(k) { - position[k] = (p->r.p[k] - lparams.left_down_position[k]) * maggs.inva; - left_down_position[k] = floor(position[k]); - relative_position[k] = position[k] - left_down_position[k]; - self_force[k] = 0.0; - local_D_field[k] = 0.0; - } + // calculate position in cell, normalized to lattice size: + FOR3D(k) { + position[k] = (p->r.p[k] - lparams.left_down_position[k]) * + maggs.inva; + left_down_position[k] = floor(position[k]); + relative_position[k] = position[k] - left_down_position[k]; + self_force[k] = 0.0; + local_D_field[k] = 0.0; + } - // Copy permittivity values to the mini-lattice: + // Copy permittivity values to the mini-lattice: - for (iz=0;izp.q; - + /* calculate position in cell, normalized to lattice size: */ FOR3D(k) { - position[k] = (P->r.p[k] - lparams.left_down_position[k]) * maggs.inva; + position[k] = (P->r.p[k] - lparams.left_down_position[k]) * maggs.inva; left_down_position[k] = floor(position[k]); - relative_position[k] = position[k] - left_down_position[k]; + relative_position[k] = position[k] - left_down_position[k]; local_force[k] = 0.0; } - - + /* Copy permittivity values to the mini-lattice: */ /* for (iz=0;izf.f[k] -= local_force[k]; - } + FOR3D(k) { P->f.f[k] -= local_force[k]; } } /** Calculate the actual force from the E-Field @@ -2157,62 +2213,57 @@ void maggs_calc_self_influence(Particle* P) @param index index of the lattice site @param grad charge gradient */ -void maggs_calc_part_link_forces(Particle *p, int index, double *grad) -{ +void maggs_calc_part_link_forces(Particle *p, int index, double *grad) { static int init = 1; static int help_index[SPACE_DIM]; int ind_grad, j; int dir1, dir2; /* int* anchor_neighb; */ - int l,m; + int l, m; double local_force[SPACE_DIM]; - - if(init) { - t_site* anchor_site; + + if (init) { + t_site *anchor_site; anchor_site = &lattice[index]; FOR3D(j) { - help_index[j] = maggs_get_offset(lattice[neighbor[index][j]].r[j], anchor_site->r[j], j, lparams.dim); + help_index[j] = maggs_get_offset(lattice[neighbor[index][j]].r[j], + anchor_site->r[j], j, lparams.dim); } init = 0; } - - FOR3D(j){ - local_force[j] = 0.; - } - - ind_grad = 0; - + + FOR3D(j) { local_force[j] = 0.; } + + ind_grad = 0; + FOR3D(j) { maggs_calc_directions(j, &dir1, &dir2); - - for(l=0;l<2;l++){ /* jumps from dir2- to dir2+ */ - for(m=0;m<2;m++){ /* jumps from dir1- to dir1+ */ - local_force[j] += -grad[ind_grad]*Dfield[3*index+j]; - //fprintf(stderr, "charge_gradient %d: %1.9f\n", ind_grad, grad[ind_grad]); - ind_grad++; - index += help_index[dir1]; - help_index[dir1] = -help_index[dir1]; + + for (l = 0; l < 2; l++) { /* jumps from dir2- to dir2+ */ + for (m = 0; m < 2; m++) { /* jumps from dir1- to dir1+ */ + local_force[j] += -grad[ind_grad] * Dfield[3 * index + j]; + // fprintf(stderr, "charge_gradient %d: %1.9f\n", ind_grad, + // grad[ind_grad]); + ind_grad++; + index += help_index[dir1]; + help_index[dir1] = -help_index[dir1]; } index += help_index[dir2]; help_index[dir2] = -help_index[dir2]; } - } - /* Attention! Here, the INTERLACING is done! */ - FOR3D(j){ - p->f.f[j] += maggs.pref1 * local_force[j]; } + /* Attention! Here, the INTERLACING is done! */ + FOR3D(j) { p->f.f[j] += maggs.pref1 * local_force[j]; } } - /** Public function. Calculates the actual force on each particle by calling all other needed functions (except for maggs_propagate_B_field) */ -void maggs_calc_forces() -{ +void maggs_calc_forces() { static int init = 1; static int Npart_old; - int d, index, Npart, ip; + int d, index, Npart, ip; double q; /* position of a particle in local lattice units */ double pos[SPACE_DIM]; @@ -2220,15 +2271,16 @@ void maggs_calc_forces() int first[3]; /* charge gradient (number of neighbor sites X number of dimensions) */ static double *grad; - - if(init) Npart_old = 0; - + + if (init) + Npart_old = 0; + Npart = cells_get_n_particles(); - if(Npart>Npart_old) { - grad = Utils::realloc(grad, 12*Npart*sizeof(double)); + if (Npart > Npart_old) { + grad = Utils::realloc(grad, 12 * Npart * sizeof(double)); Npart_old = Npart; } - + /* Hopefully only needed for Yukawa: */ maggs_update_charge_gradients(grad); @@ -2262,13 +2314,6 @@ void maggs_calc_forces() maggs_compute_dipole_correction(); } - - - - - - - /********************************************/ /****** get energy and print out stuff ******/ /********************************************/ @@ -2277,41 +2322,39 @@ void maggs_calc_forces() public function! @return returns electric energy */ -double maggs_electric_energy() -{ +double maggs_electric_energy() { int x, y, z, i, k; double localresult = 0.; double globalresult = 0.; - + FORALL_INNER_SITES(x, y, z) { - i = maggs_get_linear_index(x, y, z, lparams.dim); - FOR3D(k){ - localresult += Utils::sqr(Dfield[i*3+k]) / lattice[i].permittivity[k]; + i = maggs_get_linear_index(x, y, z, lparams.dim); + FOR3D(k) { + localresult += Utils::sqr(Dfield[i * 3 + k]) / lattice[i].permittivity[k]; } } - localresult *= 0.5*maggs.a; - MPI_Allreduce(&localresult,&globalresult,1,MPI_DOUBLE,MPI_SUM,comm_cart); + localresult *= 0.5 * maggs.a; + MPI_Allreduce(&localresult, &globalresult, 1, MPI_DOUBLE, MPI_SUM, comm_cart); return globalresult; } - /** Public funxtion. Integrates the B-field over the whole system to get the energy of the magnetic field. @return returns magnetic energy */ -double maggs_magnetic_energy() -{ +double maggs_magnetic_energy() { int x, y, z, i; double result = 0.; /* double invmass = 1./maggs.f_mass; we have B^~=B*c !!!! */ - + FORALL_INNER_SITES(x, y, z) { - i = maggs_get_linear_index(x, y, z, lparams.dim); - result += Utils::sqr(Bfield[i*3]) + Utils::sqr(Bfield[i*3+1]) + Utils::sqr(Bfield[i*3+2]); + i = maggs_get_linear_index(x, y, z, lparams.dim); + result += Utils::sqr(Bfield[i * 3]) + Utils::sqr(Bfield[i * 3 + 1]) + + Utils::sqr(Bfield[i * 3 + 2]); } /* B is rescaled !!! ATTENTION!!! */ - result *= 0.5*maggs.a; + result *= 0.5 * maggs.a; return result; } @@ -2322,35 +2365,32 @@ double maggs_magnetic_energy() /** Initialization function. Sets maggs structure variables. Calls calculation of initial D-field. */ -void maggs_init() -{ - maggs.inva = (double) maggs.mesh/box_l[0]; - maggs.a = 1.0/maggs.inva; - maggs.pref1 = sqrt(4. * M_PI * maggs.prefactor); - - if (maggs_sanity_checks()) { - runtimeErrorMsg() << "MEMD sanity checks failed."; - return; - } - - maggs_setup_local_lattice(); - - /* enforce electric field onto the Born-Oppenheimer surface */ - maggs_calc_init_e_field(); - // if(!this_node) fprintf(stderr, "%d: Electric field is initialized\n", this_node); - maggs_calc_self_energy_coeffs(); +void maggs_init() { + maggs.inva = (double)maggs.mesh / box_l[0]; + maggs.a = 1.0 / maggs.inva; + maggs.pref1 = sqrt(4. * M_PI * maggs.prefactor); + + if (maggs_sanity_checks()) { + runtimeErrorMsg() << "MEMD sanity checks failed."; + return; + } + + maggs_setup_local_lattice(); + + /* enforce electric field onto the Born-Oppenheimer surface */ + maggs_calc_init_e_field(); + // if(!this_node) fprintf(stderr, "%d: Electric field is initialized\n", + // this_node); + maggs_calc_self_energy_coeffs(); } /** Frees the dynamically allocated memory Currently not called from anywhere. */ -void maggs_exit() -{ +void maggs_exit() { free(lattice); free(neighbor); free(Dfield); free(Bfield); } - - #endif // ELECTROSTATICS diff --git a/src/core/maggs.hpp b/src/core/maggs.hpp index 77982cfc6f..71fb36c99c 100755 --- a/src/core/maggs.hpp +++ b/src/core/maggs.hpp @@ -1,23 +1,23 @@ /* Copyright (C) 2010,2011 Florian Fahrenberger Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file maggs.hpp @@ -38,12 +38,13 @@ * * Further reading on the algorithm: *
    - *
  • I. Pasichnyk and B. Dunweg, Coulomb interaction via local dynamics: a molecular-dynamics algorithm. J. Phys: Condens. Matter, 16 ,p. 1399-4020, (2004). + *
  • I. Pasichnyk and B. Dunweg, Coulomb interaction via local dynamics: a + * molecular-dynamics algorithm. J. Phys: Condens. Matter, 16 ,p. 1399-4020, + * (2004). *
- * + * */ - /** protect header file: */ #ifndef _MAGGS_H #define _MAGGS_H @@ -55,7 +56,7 @@ /** \name External structure */ /*@{*/ -/** \struct MAGGS_struct +/** \struct MAGGS_struct Maggs structure. Contains global system information for MEMD algorithm */ typedef struct { @@ -71,7 +72,7 @@ typedef struct { /** prefactor to convert field to force. */ double pref1; /** mesh size in one dimension */ - int mesh; + int mesh; /** = 1/a = mesh / box_length */ double inva; /** size of mesh cube */ @@ -100,7 +101,8 @@ void maggs_init(); /** called from: initialize.cpp */ @param finite_epsilon_flag whether to do epsilon-at-infinity-correction @param epsilon_infty epsilon-at-infinity */ -int maggs_set_parameters(double prefactor, double f_mass, int mesh, int finite_epsilon_flag, double epsilon_infty); +int maggs_set_parameters(double prefactor, double f_mass, int mesh, + int finite_epsilon_flag, double epsilon_infty); /** get lattice size in one dimension @return mesh in 1D @@ -111,28 +113,35 @@ int maggs_get_mesh_1D(); @param node_x index of the node in x direction @param node_y index of the node in y direction @param node_z index of the node in z direction - @param direction direction in which the link points from the node. 0 is for x, 1 is for y, 2 is for z - @param relative_epsilon permittivity to set, relative to the background permittivity set by the electrostatics prefactor + @param direction direction in which the link points from the node. 0 + is for x, 1 is for y, 2 is for z + @param relative_epsilon permittivity to set, relative to the background + permittivity set by the electrostatics prefactor */ -double maggs_set_permittivity(int node_x, int node_y, int node_z, int direction, double relative_epsilon); +double maggs_set_permittivity(int node_x, int node_y, int node_z, int direction, + double relative_epsilon); /** set adaptive permittivity flag - @param scaling scaling of the volumetric formula for salt dependent permittivity + @param scaling scaling of the volumetric formula for salt dependent + permittivity */ int maggs_set_adaptive_flag(double scaling); /** Propagate the B-field in the system. - Called TWICE from \ref integrate.cpp with timestep dt/2 to ensure time-reversibility of the integrator. + Called TWICE from \ref integrate.cpp with timestep dt/2 to ensure + time-reversibility of the integrator. @param dt Timestep for which to propagate the field. */ void maggs_propagate_B_field(double dt); -/** Calculate the forces on all particles. Writes the result directly into the force pointer. */ +/** Calculate the forces on all particles. Writes the result directly into the + * force pointer. */ void maggs_calc_forces(); /** Get the electric energy of the system as return value */ double maggs_electric_energy(); -/** Get the magnetic energy of the artificial transversal field component as return value */ +/** Get the magnetic energy of the artificial transversal field component as + * return value */ double maggs_magnetic_energy(); /** Count the number of charges in the whole system. */ diff --git a/src/core/magnetic_non_p3m_methods.cpp b/src/core/magnetic_non_p3m_methods.cpp index 8f64b8187f..b7f2cccec7 100755 --- a/src/core/magnetic_non_p3m_methods.cpp +++ b/src/core/magnetic_non_p3m_methods.cpp @@ -34,10 +34,10 @@ */ #include "magnetic_non_p3m_methods.hpp" -#include "thermostat.hpp" -#include "interaction_data.hpp" -#include "grid.hpp" #include "cells.hpp" +#include "grid.hpp" +#include "interaction_data.hpp" +#include "thermostat.hpp" #ifdef DIPOLES diff --git a/src/core/mdlc_correction.cpp b/src/core/mdlc_correction.cpp index 8a22847e9c..a66315c924 100755 --- a/src/core/mdlc_correction.cpp +++ b/src/core/mdlc_correction.cpp @@ -36,12 +36,12 @@ #include "mdlc_correction.hpp" #include "cells.hpp" #include "communication.hpp" +#include "debug.hpp" #include "global.hpp" #include "grid.hpp" #include "p3m-dipolar.hpp" #include "particle_data.hpp" #include "utils.hpp" -#include "debug.hpp" #ifdef DIPOLES @@ -124,8 +124,10 @@ double slab_dip_count_mu(double *mt, double *mx, double *my) { **************************************************************************************************** */ -double get_DLC_dipolar(int kcut, std::vector & fx, std::vector & fy, std::vector & fz, - std::vector & tx, std::vector & ty, std::vector & tz) { +double get_DLC_dipolar(int kcut, std::vector &fx, + std::vector &fy, std::vector &fz, + std::vector &tx, std::vector &ty, + std::vector &tz) { int ix, iy, ip; double gx, gy, gr; @@ -134,8 +136,10 @@ double get_DLC_dipolar(int kcut, std::vector & fx, std::vector & // {Re(S+), Im(S+), Re(S-), Im(S-)} std::vector ReSjp(n_local_particles), ReSjm(n_local_particles); std::vector ImSjp(n_local_particles), ImSjm(n_local_particles); - std::vector ReGrad_Mup(n_local_particles), ImGrad_Mup(n_local_particles); - std::vector ReGrad_Mum(n_local_particles), ImGrad_Mum(n_local_particles); + std::vector ReGrad_Mup(n_local_particles), + ImGrad_Mup(n_local_particles); + std::vector ReGrad_Mum(n_local_particles), + ImGrad_Mum(n_local_particles); double a, b, c, d, er, ez, f, fa1; double s1, s2, s3, s4; double s1z, s2z, s3z, s4z; @@ -388,8 +392,10 @@ double get_DLC_energy_dipolar(int kcut) { void add_mdlc_force_corrections() { int i, ip; int dip_DLC_kcut; - std::vector dip_DLC_f_x(n_part), dip_DLC_f_y(n_part), dip_DLC_f_z(n_part); - std::vector dip_DLC_t_x(n_part), dip_DLC_t_y(n_part), dip_DLC_t_z(n_part); + std::vector dip_DLC_f_x(n_part), dip_DLC_f_y(n_part), + dip_DLC_f_z(n_part); + std::vector dip_DLC_t_x(n_part), dip_DLC_t_y(n_part), + dip_DLC_t_z(n_part); double dip_DLC_energy = 0.0; double mz = 0.0, mx = 0.0, my = 0.0, volume, mtot = 0.0; #if defined(ROTATION) && defined(DP3M) diff --git a/src/core/metadynamics.cpp b/src/core/metadynamics.cpp index 99538ea4bc..7b0cd0c640 100755 --- a/src/core/metadynamics.cpp +++ b/src/core/metadynamics.cpp @@ -113,8 +113,8 @@ void meta_perform() { if (p.p.identity == meta_pid1) { flag1 = 1; p1 = &p; - ppos1=unfolded_position(p); - + ppos1 = unfolded_position(p); + if (flag1 && flag2) { /* vector r2-r1 - Not a minimal image! Unfolded position */ meta_cur_xi = ppos2 - ppos1; @@ -124,11 +124,11 @@ void meta_perform() { if (p.p.identity == meta_pid2) { flag2 = 1; p2 = &p; - ppos2=unfolded_position(p); + ppos2 = unfolded_position(p); if (flag1 && flag2) { /* vector r2-r1 - Not a minimal image! Unfolded position */ - meta_cur_xi =ppos2 - ppos1; + meta_cur_xi = ppos2 - ppos1; break; } } @@ -157,7 +157,7 @@ void meta_perform() { } // direction of the bias force - meta_apply_direction =meta_cur_xi /meta_cur_xi.norm(); + meta_apply_direction = meta_cur_xi / meta_cur_xi.norm(); } else if (meta_switch == META_REL_Z) { // reaction coordinate value: relative height of z_pid1 with respect to // z_pid2 @@ -182,7 +182,7 @@ void meta_perform() { /** Apply force */ // Calculate the strength of the applied force - double factor=0; + double factor = 0; if (meta_val_xi < meta_xi_min) { // below the lower bound factor = -1. * meta_f_bound * (meta_xi_min - meta_val_xi) / meta_xi_step; diff --git a/src/core/minimize_energy.cpp b/src/core/minimize_energy.cpp index 6b11a85344..f7c1c25e81 100644 --- a/src/core/minimize_energy.cpp +++ b/src/core/minimize_energy.cpp @@ -20,12 +20,12 @@ */ #include "minimize_energy.hpp" +#include "cells.hpp" +#include "communication.hpp" #include "initialize.hpp" #include "integrate.hpp" #include "rotation.hpp" #include "utils.hpp" -#include "communication.hpp" -#include "cells.hpp" #include #include diff --git a/src/core/minimize_energy.hpp b/src/core/minimize_energy.hpp index f52df321d6..931808bd3d 100644 --- a/src/core/minimize_energy.hpp +++ b/src/core/minimize_energy.hpp @@ -2,28 +2,29 @@ Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef __MINIMIZE_ENERGY_HPP #define __MINIMIZE_ENERGY_HPP bool minimize_energy(void); -void minimize_energy_init(const double f_max, const double gamma, const int max_steps, const double max_displacement); +void minimize_energy_init(const double f_max, const double gamma, + const int max_steps, const double max_displacement); bool steepest_descent_step(void); #endif /* __MINIMIZE_ENERGY */ diff --git a/src/core/mmm-common.cpp b/src/core/mmm-common.cpp index 71bbc1ef65..003f332acf 100755 --- a/src/core/mmm-common.cpp +++ b/src/core/mmm-common.cpp @@ -1,31 +1,35 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file mmm-common.cpp Common parts of the MMM family of methods for the - electrostatic interaction, MMM1D, MMM2D and ELC. This file contains the code for the polygamma + electrostatic interaction, MMM1D, MMM2D and ELC. This file contains the + code for the polygamma expansions used for the near formulas of MMM1D and MMM2D. - The expansion of the polygamma functions is fairly easy and follows directly from Abramowitz and Stegun. - For details, see Axel Arnold and Christian Holm, "MMM2D: A fast and accurate summation method for - electrostatic interactions in 2D slab geometries", Comp. Phys. Comm., 148/3(2002),327-348. + The expansion of the polygamma functions is fairly easy and follows directly + from Abramowitz and Stegun. + For details, see Axel Arnold and Christian Holm, "MMM2D: A fast and accurate + summation method for + electrostatic interactions in 2D slab geometries", Comp. Phys. Comm., + 148/3(2002),327-348. */ #include "config.hpp" @@ -34,95 +38,93 @@ #include "utils.hpp" std::vector modPsi; -int n_modPsi = 0; +int n_modPsi = 0; -static void preparePolygammaEven(int n, double binom, Polynom &series) -{ +static void preparePolygammaEven(int n, double binom, Polynom &series) { /* (-0.5 n) psi^2n/2n! (-0.5 n) and psi^(2n+1)/(2n)! series expansions note that BOTH carry 2n! */ int order; double deriv; double maxx, x_order, coeff, pref; - deriv = 2*n; + deriv = 2 * n; if (n == 0) { // psi^0 has a slightly different series expansion maxx = 0.25; series.resize(1); - series[0] = 2*(1 - C_GAMMA); + series[0] = 2 * (1 - C_GAMMA); for (order = 1;; order += 1) { - x_order = 2*order; - coeff = -2*hzeta(x_order + 1, 2); - if (fabs(maxx*coeff)*(4.0/3.0) < ROUND_ERROR_PREC) - break; + x_order = 2 * order; + coeff = -2 * hzeta(x_order + 1, 2); + if (fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC) + break; series.push_back(coeff); maxx *= 0.25; } - } - else { + } else { // even, n > 0 maxx = 1; pref = 2; - + for (order = 0;; order++) { // only even exponents of x - x_order = 2*order; - coeff = pref*hzeta(1 + deriv + x_order, 2); - if ((fabs(maxx*coeff)*(4.0/3.0) < ROUND_ERROR_PREC) && (x_order > deriv)) - break; - series.push_back(-binom*coeff); + x_order = 2 * order; + coeff = pref * hzeta(1 + deriv + x_order, 2); + if ((fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC) && + (x_order > deriv)) + break; + series.push_back(-binom * coeff); maxx *= 0.25; - pref *= (1.0 + deriv/(x_order + 1)); - pref *= (1.0 + deriv/(x_order + 2)); + pref *= (1.0 + deriv / (x_order + 1)); + pref *= (1.0 + deriv / (x_order + 2)); } } } -static void preparePolygammaOdd(int n, double binom, Polynom &series) -{ +static void preparePolygammaOdd(int n, double binom, Polynom &series) { int order; double deriv; double maxx, x_order, coeff, pref; - deriv = 2*n + 1; + deriv = 2 * n + 1; maxx = 0.5; // to get 1/(2n)! instead of 1/(2n+1)! - pref = 2*deriv*(1 + deriv); + pref = 2 * deriv * (1 + deriv); for (order = 0;; order++) { // only odd exponents of x - x_order = 2*order + 1; - coeff = pref*hzeta(1 + deriv + x_order, 2); - if ((fabs(maxx*coeff)*(4.0/3.0) < ROUND_ERROR_PREC) && (x_order > deriv)) + x_order = 2 * order + 1; + coeff = pref * hzeta(1 + deriv + x_order, 2); + if ((fabs(maxx * coeff) * (4.0 / 3.0) < ROUND_ERROR_PREC) && + (x_order > deriv)) break; - series.push_back( -binom*coeff); + series.push_back(-binom * coeff); maxx *= 0.25; - pref *= (1.0 + deriv/(x_order + 1)); - pref *= (1.0 + deriv/(x_order + 2)); + pref *= (1.0 + deriv / (x_order + 1)); + pref *= (1.0 + deriv / (x_order + 2)); } } -void create_mod_psi_up_to(int new_n) -{ +void create_mod_psi_up_to(int new_n) { int n; double binom; if (new_n > n_modPsi) { int old = n_modPsi; n_modPsi = new_n; - modPsi.resize(2*n_modPsi); + modPsi.resize(2 * n_modPsi); binom = 1.0; for (n = 0; n < old; n++) - binom *= (-0.5 - n)/(double)(n+1); + binom *= (-0.5 - n) / (double)(n + 1); for (; n < n_modPsi; n++) { - preparePolygammaEven(n, binom, modPsi[2*n]); - preparePolygammaOdd(n, binom, modPsi[2*n + 1]); - binom *= (-0.5 - n)/(double)(n+1); + preparePolygammaEven(n, binom, modPsi[2 * n]); + preparePolygammaOdd(n, binom, modPsi[2 * n + 1]); + binom *= (-0.5 - n) / (double)(n + 1); } } } diff --git a/src/core/mmm-common.hpp b/src/core/mmm-common.hpp index 6dafd525b3..809d4bc818 100755 --- a/src/core/mmm-common.hpp +++ b/src/core/mmm-common.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file mmm-common.hpp modified polygamma functions. See Arnold,Holm 2002 @@ -31,23 +31,25 @@ /** \name Math Constants */ /*@{*/ -#define C_2PI (2*M_PI) -#define C_GAMMA 0.57721566490153286060651209008 +#define C_2PI (2 * M_PI) +#define C_GAMMA 0.57721566490153286060651209008 #define C_2LOG4PI -5.0620484939385815859557831885 -#define C_2PISQR C_2PI*C_2PI +#define C_2PISQR C_2PI *C_2PI /*@}*/ /** table of the Taylor expansions of the modified polygamma functions */ extern std::vector modPsi; -extern int n_modPsi; +extern int n_modPsi; /** modified polygamma for even order 2*n, n >= 0 */ -inline double mod_psi_even(int n, double x) -{ return evaluateAsTaylorSeriesAt(&modPsi[2*n],x*x); } +inline double mod_psi_even(int n, double x) { + return evaluateAsTaylorSeriesAt(&modPsi[2 * n], x * x); +} /** modified polygamma for odd order 2*n+1, n>= 0 */ -inline double mod_psi_odd(int n, double x) -{ return x*evaluateAsTaylorSeriesAt(&modPsi[2*n+1], x*x); } +inline double mod_psi_odd(int n, double x) { + return x * evaluateAsTaylorSeriesAt(&modPsi[2 * n + 1], x * x); +} /** create the both the even and odd polygamma functions up to order 2*n */ void create_mod_psi_up_to(int n); diff --git a/src/core/mmm1d.hpp b/src/core/mmm1d.hpp index 36c5e0edfd..3d8f162a02 100755 --- a/src/core/mmm1d.hpp +++ b/src/core/mmm1d.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file mmm1d.hpp MMM1D algorithm for long range coulomb interactions. Implementation of the MMM1D method for the calculation of the electrostatic @@ -28,8 +28,8 @@ #ifndef MMM1D_H #define MMM1D_H -#include "utils.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef ELECTROSTATICS @@ -40,16 +40,21 @@ typedef struct { /** required accuracy */ double maxPWerror; /** cutoff of the bessel sum. only used by the GPU implementation */ - int bessel_cutoff; + int bessel_cutoff; } MMM1D_struct; extern MMM1D_struct mmm1d_params; -/** parameters for MMM1D. Most of the parameters can also be tuned automatically. Unlike - P3M, this tuning is redone automatically whenever parameters change, but not immediately +/** parameters for MMM1D. Most of the parameters can also be tuned + automatically. Unlike + P3M, this tuning is redone automatically whenever parameters change, but not + immediately if you set this parameters. - @param switch_rad at which xy-distance the calculation switches from the far to the - near formula. If -1, this parameter will be tuned automatically. - @param maxPWerror the maximal allowed error for the potential and the forces without the + @param switch_rad at which xy-distance the calculation switches from the far + to the + near formula. If -1, this parameter will be tuned + automatically. + @param maxPWerror the maximal allowed error for the potential and the forces + without the prefactors, i. e. for the pure lattice 1/r-sum. */ int MMM1D_set_params(double switch_rad, double maxPWerror); @@ -61,10 +66,11 @@ void MMM1D_init(); /// void add_mmm1d_coulomb_pair_force(double chprf, double d[3], double dist2, - double dist, double force[3]); + double dist, double force[3]); /// -double mmm1d_coulomb_pair_energy(Particle *p1, Particle *p2, double d[3], double r2, double r); +double mmm1d_coulomb_pair_energy(Particle *p1, Particle *p2, double d[3], + double r2, double r); /** tuning of the parameters which are not set by the user, e.g. the switching radius or the bessel_cutoff. Call this only on the master node. diff --git a/src/core/mmm2d.hpp b/src/core/mmm2d.hpp index dcc10004fa..b9ba6572b9 100755 --- a/src/core/mmm2d.hpp +++ b/src/core/mmm2d.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file mmm2d.hpp MMM2D algorithm for long range coulomb interaction in 2d+h geometries. Implementation of the MMM2D method for the calculation @@ -42,9 +42,12 @@ typedef struct { double maxPWerror; /** far formula cutoff and its square */ double far_cut, far_cut2; - /** if nonzero, \ref MMM2D_struct::far_cut has been calculated by \ref MMM2D_tune_far, and will be - recalculated automatically, if important parameters, such as the number of cells, change. If this - is zero, the far cutoff has been set explicitly by the user and will not be touched by Espresso. */ + /** if nonzero, \ref MMM2D_struct::far_cut has been calculated by \ref + MMM2D_tune_far, and will be + recalculated automatically, if important parameters, such as the number of + cells, change. If this + is zero, the far cutoff has been set explicitly by the user and will not + be touched by Espresso. */ int far_calculated; /// whether there is dielectric contrast int dielectric_contrast_on; @@ -56,45 +59,46 @@ typedef struct { } MMM2D_struct; extern MMM2D_struct mmm2d_params; -/** set parameters for MMM2D. This assumes that the particles do NOT leave the box. - For the near formula (nsquared cell structure), precision might be lost, while - the far formula might have problems with overflows. - @param maxPWerror the maximal error for the pairwise interactions. Both for - potential and force components. The potential is therefore +/** set parameters for MMM2D. This assumes that the particles do NOT leave the + box. + For the near formula (nsquared cell structure), precision might be lost, + while + the far formula might have problems with overflows. + @param maxPWerror the maximal error for the pairwise interactions. Both + for + potential and force components. The potential is + therefore always slightly more precise @param far_cut sets the cutoff for the far formula in inverse lengths. If -1, the far cutoff is determined by maxPWerror. - Manual setting is probably only good for testing + Manual setting is probably only good for testing @param delta_top dielectric contrast at top of the simulation box @param delta_mid dielectric contrast in the middle of the simulation box */ -int MMM2D_set_params(double maxPWerror, double far_cut, double delta_top, double delta_bot, int const_pot_on, double pot_diff); +int MMM2D_set_params(double maxPWerror, double far_cut, double delta_top, + double delta_bot, int const_pot_on, double pot_diff); /** the general long range force/energy calculation */ double MMM2D_add_far(int f, int e); /** the actual long range force calculation */ -inline void MMM2D_add_far_force() { - MMM2D_add_far(1,0); -} +inline void MMM2D_add_far_force() { MMM2D_add_far(1, 0); } /** the actual long range energy calculation */ -inline double MMM2D_far_energy() { - return MMM2D_add_far(0,1); -} +inline double MMM2D_far_energy() { return MMM2D_add_far(0, 1); } /** pairwise calculated parts of MMM2D force (near neighbors) */ -void add_mmm2d_coulomb_pair_force(double charge_factor, - double dv[3], double d2, double d, double f[3]); +void add_mmm2d_coulomb_pair_force(double charge_factor, double dv[3], double d2, + double d, double f[3]); /** pairwise calculated parts of MMM2D force (near neighbors) */ -double mmm2d_coulomb_pair_energy(double charge_factor, - double dv[3], double d2, double d); +double mmm2d_coulomb_pair_energy(double charge_factor, double dv[3], double d2, + double d); /// check that MMM2D can run with the current parameters int MMM2D_sanity_checks(); -/// initialize the MMM2D constants +/// initialize the MMM2D constants void MMM2D_init(); /** if the number of particles has changed (even per node), @@ -102,10 +106,10 @@ void MMM2D_init(); void MMM2D_on_resort_particles(); /** energy contribution from dielectric layers */ -double MMM2D_dielectric_layers_energy_contribution(); +double MMM2D_dielectric_layers_energy_contribution(); /** force contribution from dielectric layers */ -void MMM2D_dielectric_layers_force_contribution(); +void MMM2D_dielectric_layers_force_contribution(); #endif diff --git a/src/core/molforces.cpp b/src/core/molforces.cpp index 2386464892..a4010a0fd6 100755 --- a/src/core/molforces.cpp +++ b/src/core/molforces.cpp @@ -225,7 +225,7 @@ void mpi_comm_mol_info(IntList *local_trapped_mols) { for (i = 1; i < n_nodes; i++) { sum_n_local_mols += n_local_mols[i]; } - std::vectorlocal_mols(sum_n_local_mols); + std::vector local_mols(sum_n_local_mols); /* Everyone tells me which trapped molecules are on their node */ count = 0; diff --git a/src/core/morse.cpp b/src/core/morse.cpp index 0009bddbf6..beb8531d87 100755 --- a/src/core/morse.cpp +++ b/src/core/morse.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file morse.cpp * @@ -27,23 +27,22 @@ #ifdef MORSE -int morse_set_params(int part_type_a, int part_type_b, - double eps, double alpha, - double rmin, double cut) -{ +int morse_set_params(int part_type_a, int part_type_b, double eps, double alpha, + double rmin, double cut) { double add1, add2; IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; - data->MORSE_eps = eps; + data->MORSE_eps = eps; data->MORSE_alpha = alpha; - data->MORSE_rmin = rmin; - data->MORSE_cut = cut; + data->MORSE_rmin = rmin; + data->MORSE_cut = cut; /* calculate dependent parameter */ - add1 = exp(-2.0*data->MORSE_alpha*(data->MORSE_cut - data->MORSE_rmin)); - add2 = 2.0*exp(-data->MORSE_alpha*(data->MORSE_cut - data->MORSE_rmin)); + add1 = exp(-2.0 * data->MORSE_alpha * (data->MORSE_cut - data->MORSE_rmin)); + add2 = 2.0 * exp(-data->MORSE_alpha * (data->MORSE_cut - data->MORSE_rmin)); data->MORSE_rest = data->MORSE_eps * (add1 - add2); /* broadcast interaction parameters */ diff --git a/src/core/myconfig-default.hpp b/src/core/myconfig-default.hpp index 59efb8ad3e..afde7ebd64 100755 --- a/src/core/myconfig-default.hpp +++ b/src/core/myconfig-default.hpp @@ -52,14 +52,13 @@ #define LB #define LB_BOUNDARIES #ifdef CUDA - #define LB_GPU - #define LB_BOUNDARIES_GPU -#endif +#define LB_GPU +#define LB_BOUNDARIES_GPU +#endif // Electrokinetics #ifdef CUDA - #define ELECTROKINETICS - #define EK_BOUNDARIES - #define EK_ELECTROSTATIC_COUPLING +#define ELECTROKINETICS +#define EK_BOUNDARIES +#define EK_ELECTROSTATIC_COUPLING #endif - diff --git a/src/core/npt.cpp b/src/core/npt.cpp index 86b22512fb..90b0aea470 100644 --- a/src/core/npt.cpp +++ b/src/core/npt.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "npt.hpp" - +#include "config.hpp" diff --git a/src/core/npt.hpp b/src/core/npt.hpp index 4410643288..558e01bc96 100755 --- a/src/core/npt.hpp +++ b/src/core/npt.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file npt.hpp exports for the NPT code, which otherwise is really spread all over... @@ -31,8 +31,9 @@ * data types ************************************************/ -/** Structure to hold all variables related to the isotropic NpT-integration scheme. */ -typedef struct { +/** Structure to hold all variables related to the isotropic NpT-integration + * scheme. */ +typedef struct { /** mass of a virtual piston representing the shaken box */ double piston; /** inverse of piston */ @@ -55,7 +56,7 @@ typedef struct { /** ideal gas components of \ref p_inst, derived from the velocities */ double p_vel[3]; /** flag which indicates if \ref p_vel may (0) or may not (1) be used - in offline pressure calculations such as 'analyze p_inst' */ + in offline pressure calculations such as 'analyze p_inst' */ int invalidate_p_vel; /** geometry information for the npt integrator. Holds the vector where a positive value for dir indicates that @@ -65,13 +66,17 @@ typedef struct { int geometry; /** bitwise comparison values corresponding to different directions*/ int nptgeom_dir[3]; - /** The number of dimensions in which npt boxlength motion is coupled to particles */ + /** The number of dimensions in which npt boxlength motion is coupled to + * particles */ int dimension; - /** Set this flag if you want all box dimensions to be identical. Needed for electrostatics and magnetostatics. - If the value of dimension is less than 3 then box length motion in one or more + /** Set this flag if you want all box dimensions to be identical. Needed for + electrostatics and magnetostatics. + If the value of dimension is less than 3 then box length motion in one or + more directions will be decoupled from the particle motion */ int cubic_box; - /** An index to one of the non_constant dimensions. handy if you just want the variable box_l */ + /** An index to one of the non_constant dimensions. handy if you just want the + * variable box_l */ int non_const_dim; } nptiso_struct; extern nptiso_struct nptiso; diff --git a/src/core/nsquare.hpp b/src/core/nsquare.hpp index 5c6c4030dc..0f49a88610 100755 --- a/src/core/nsquare.hpp +++ b/src/core/nsquare.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef NSQUARE_H #define NSQUARE_H @@ -29,7 +29,7 @@ cell per other node. The communication is done via broadcasts (exchange_ghosts and update_ghosts) and reduce operations (collect_ghost_force). - + The algorithm used for interaction calculation is parallelized, but a full communication is needed every time step. Let us assume that the number of nodes P is odd. Then a node p will do the diff --git a/src/core/object-in-fluid/affinity.cpp b/src/core/object-in-fluid/affinity.cpp index 00494e1649..fbc23f5740 100644 --- a/src/core/object-in-fluid/affinity.cpp +++ b/src/core/object-in-fluid/affinity.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file affinity.cpp * @@ -27,21 +27,22 @@ #ifdef AFFINITY -int affinity_set_params(int part_type_a, int part_type_b, - int afftype, double kappa, double r0, double Kon, double Koff, double maxBond, double cut) -{ +int affinity_set_params(int part_type_a, int part_type_b, int afftype, + double kappa, double r0, double Kon, double Koff, + double maxBond, double cut) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; + + data->affinity_type = afftype; + data->affinity_kappa = kappa; + data->affinity_r0 = r0; + data->affinity_Kon = Kon; + data->affinity_Koff = Koff; + data->affinity_maxBond = maxBond; + data->affinity_cut = cut; - data->affinity_type = afftype; - data->affinity_kappa = kappa; - data->affinity_r0 = r0; - data->affinity_Kon = Kon; - data->affinity_Koff = Koff; - data->affinity_maxBond = maxBond; - data->affinity_cut = cut; - /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); @@ -49,4 +50,3 @@ int affinity_set_params(int part_type_a, int part_type_b, } #endif - diff --git a/src/core/object-in-fluid/affinity.hpp b/src/core/object-in-fluid/affinity.hpp index b5e29a24e4..a8270aea54 100644 --- a/src/core/object-in-fluid/affinity.hpp +++ b/src/core/object-in-fluid/affinity.hpp @@ -1,644 +1,861 @@ /* Copyright (C) 2010,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef AFFINITY_H #define AFFINITY_H /** \file affinity.hpp - * Routines to calculate the affinity force + * Routines to calculate the affinity force * for a particle pair. * \ref forces.cpp */ -#include "../utils.hpp" +#include "../grid.hpp" +#include "../integrate.hpp" #include "../interaction_data.hpp" #include "../particle_data.hpp" -#include "../integrate.hpp" #include "../random.hpp" -#include "../grid.hpp" - +#include "../utils.hpp" #ifdef AFFINITY -int affinity_set_params(int part_type_a, int part_type_b, - int afftype, double kappa, double r0, double Kon, double Koff, double maxBond, double cut); +int affinity_set_params(int part_type_a, int part_type_b, int afftype, + double kappa, double r0, double Kon, double Koff, + double maxBond, double cut); /** Calculate soft-sphere potential force between particle p1 and p2 */ -inline void add_affinity_pair_force(Particle * p1, Particle * p2, IA_parameters *ia_params, - double d[3], double dist, double force[3]) -{ +inline void add_affinity_pair_force(Particle *p1, Particle *p2, + IA_parameters *ia_params, double d[3], + double dist, double force[3]) { -// The affinity potential has the first argument affinity_type. This is to differentiate between different implementations. For example one implementation can take into account the detachment force, another not. + // The affinity potential has the first argument affinity_type. This is to + // differentiate between different implementations. For example one + // implementation can take into account the detachment force, another not. int aff_type_extracted = 0; int period_for_output = -1; - if (ia_params->affinity_type > 10 ) { - aff_type_extracted = ia_params->affinity_type % 10; - period_for_output = ia_params->affinity_type - aff_type_extracted; } - else aff_type_extracted = ia_params->affinity_type; - if ( aff_type_extracted == 1 ) { - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is, whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintain the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * comments: - * strength of the force is proportiona to the difference of actual bond length and relaxed bond length - * bond is always created, no probability is involved - * if bondlength reaches maxBond, the bond imediately ruptures. No probability is involved - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos =unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - if (len > ia_params->affinity_r0) { - fac = ia_params->affinity_kappa*(len - ia_params->affinity_r0); - //printf("len %f r0 %f\n",len, ia_params->affinity_r0); - } - else fac = 0.0; -// double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j] / len; - } -// printf("%f ",ftemp); - // Decision whether I should break the bond: if the bond length is greater than maxBond, it breaks. - if (len > ia_params->affinity_maxBond) { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - // This implementation creates bond always - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } - } - } + if (ia_params->affinity_type > 10) { + aff_type_extracted = ia_params->affinity_type % 10; + period_for_output = ia_params->affinity_type - aff_type_extracted; + } else + aff_type_extracted = ia_params->affinity_type; + if (aff_type_extracted == 1) { + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is, whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintain the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * comments: + * strength of the force is proportiona to the difference of actual bond + *length and relaxed bond length + * bond is always created, no probability is involved + * if bondlength reaches maxBond, the bond imediately ruptures. No + *probability is involved + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + if (len > ia_params->affinity_r0) { + fac = ia_params->affinity_kappa * (len - ia_params->affinity_r0); + // printf("len %f r0 %f\n",len, ia_params->affinity_r0); + } else + fac = 0.0; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j] / len; + } + // printf("%f ",ftemp); + // Decision whether I should break the bond: if the bond length is + // greater than maxBond, it breaks. + if (len > ia_params->affinity_maxBond) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + // This implementation creates bond always + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } + } + } } - if ( aff_type_extracted == 2 ) { //second implementation of affinity - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintaind the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * - * comments: - * strength of the force is proportiona to the difference of actual bond length and relaxed bond length - * bond is created with probability 1-exp(-Kon*timestep) - * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake the bond - * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = K0*exp(kappa(r-r0)/Fd) - * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. - * here, maxBond is used as detachment force F_d. The original check for ensuring, that partice flows out of the cut-off radius and the bond remains active is replaced with fixed check, that bond length must not be greater that 0.8 cut_off - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - if (len > ia_params->affinity_r0) { - fac = ia_params->affinity_kappa*(len - ia_params->affinity_r0); - //printf("len %f r0 %f\n",len, ia_params->affinity_r0); - } - else fac = 0.0; - //double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j] / len; -// ftemp += abs(fac * vec[j] / len); - } - //if (ftemp > 0.000000000000001) printf("%f ",fac); - // Decision whether I should break the bond: - // First, force exerted on bond is stored in fac - double tmpF = fac; - // Then, zero force off rate K_0 is stored at ia_params_Koff - double tmpK0 = ia_params->affinity_Koff; - // Then, detachment force is stored in ia_params->affinity_maxBond - double tmpFd = ia_params->affinity_maxBond; - // Then, compute Koff - double tmpKoff = tmpK0*exp( tmpF / tmpFd); - // Finally, compute Poff - double Poff = 1.0 - exp( - tmpKoff*time_step); - //printf("%f ", Poff); - if (len < 0.8*ia_params->affinity_cut) { // in other implementation, maxBond is used here. However, in this implementation, we need maxBond for setting detachment force F_d - double decide = d_random(); - if ( decide < Poff ) - { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; -// printf("bond broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",Poff,tmpF,tmpKoff,tmpK0,len); - } - - } else { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - //printf("breaking: out of cut"); - } - // Checkpoint output: - if (period_for_output > 0 ) if (((int)floor(sim_time/time_step) % period_for_output == 0 ) && (len > ia_params->affinity_r0) ) { - FILE *fp; - double tmpPon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - fp = fopen("affinity_check.dat","a"); - fprintf(fp,"sim_time %f, period_for_output %d aff type: %d ",sim_time,period_for_output,aff_type_extracted); - fprintf(fp,"Pon %f, Kon %f, particle %d, Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff,tmpF,tmpKoff,tmpK0,len); - fclose(fp); - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - double Pon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - // The probability is given by function Pon(x)= 1 - e^(-x) where x is Kon*dt. Here is a table of values of this function, just to have an idea about the values - // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.5 | 2.0 | 3.0 | 5.0 - // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | 0.77 | 0.84 | 0.95 | 0.99 - double decide = d_random(); - if ( decide < Pon ) - { // the bond will be created only with probability Pon. - //printf("Creating: Pon = %f, decide = %f", Pon, decide); - double folded_pos[3]; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - //printf("d: %f %f %f\n",d[0],d[1],d[2]); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } else { - //printf("In range, not creating: Pon = %f, decide = %f", Pon, decide); - } - } - } - } - } - if ( aff_type_extracted == 3 ) { - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintaind the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * - * comments: - * strength of the force is proportiona to the difference of actual bond length and relaxed bond length - * bond is created with probability 1-exp(-Kon*timestep) - * bond is ruptured with probability 1-exp(-Koff*timestep) to brake the bond - * Koff is given as parameter, is not dependent on the force nor the bond length - * here, maxBond stands for ensuring, that partice flows out of the cut-off radius and the bond remains active. maxBond should be always less than cut_off radius - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - if (len > ia_params->affinity_r0) { - fac = ia_params->affinity_kappa*(len - ia_params->affinity_r0)/len; - //printf("len %f r0 %f\n",len, ia_params->affinity_r0); - } - else fac = 0.0; -// double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j]; - } -// printf("%f ",ftemp); - // Decision whether I should break the bond: - // The random decision algorithm is much more complicated with Fd detachment force etc. Here, I use much simpler rule, the same as with Kon, except that the probability of bond breakage increases with prolongation of the bond. If the bond reaches - - double Poff = 1.0 - exp( - ia_params->affinity_Koff*time_step); - if (len < ia_params->affinity_maxBond) { - double decide = d_random(); - if ( decide < Poff ) - { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - } - - } else { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - //printf("breaking: out of cut"); - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - double Pon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - // The probability is given by function Pon(x)= 1 - e^(-x) where x is Kon*dt. Here is a table of values of this function, just to have an idea about the values - // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.5 | 2.0 | 3.0 | 5.0 - // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | 0.77 | 0.84 | 0.95 | 0.99 - double decide = d_random(); - if ( decide < Pon ) - { // the bond will be created only with probability Pon. - //printf("Creating: Pon = %f, decide = %f", Pon, decide); - double folded_pos[3]; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - //printf("d: %f %f %f\n",d[0],d[1],d[2]); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } else { - //printf("In range, not creating: Pon = %f, decide = %f", Pon, decide); - } - } - } - } + if (aff_type_extracted == 2) { // second implementation of affinity + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintaind the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * + * comments: + * strength of the force is proportiona to the difference of actual bond + *length and relaxed bond length + * bond is created with probability 1-exp(-Kon*timestep) + * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake + *the bond + * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = + *K0*exp(kappa(r-r0)/Fd) + * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. + * here, maxBond is used as detachment force F_d. The original check for + *ensuring, that partice flows out of the cut-off radius and the bond remains + *active is replaced with fixed check, that bond length must not be greater + *that 0.8 cut_off + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + if (len > ia_params->affinity_r0) { + fac = ia_params->affinity_kappa * (len - ia_params->affinity_r0); + // printf("len %f r0 %f\n",len, ia_params->affinity_r0); + } else + fac = 0.0; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j] / len; + // ftemp += abs(fac * vec[j] / + //len); + } + // if (ftemp > 0.000000000000001) printf("%f ",fac); + // Decision whether I should break the bond: + // First, force exerted on bond is stored in fac + double tmpF = fac; + // Then, zero force off rate K_0 is stored at ia_params_Koff + double tmpK0 = ia_params->affinity_Koff; + // Then, detachment force is stored in ia_params->affinity_maxBond + double tmpFd = ia_params->affinity_maxBond; + // Then, compute Koff + double tmpKoff = tmpK0 * exp(tmpF / tmpFd); + // Finally, compute Poff + double Poff = 1.0 - exp(-tmpKoff * time_step); + // printf("%f ", Poff); + if (len < 0.8 * ia_params->affinity_cut) { // in other implementation, + // maxBond is used here. + // However, in this + // implementation, we need + // maxBond for setting + // detachment force F_d + double decide = d_random(); + if (decide < Poff) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("bond + //broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f + //\n",Poff,tmpF,tmpKoff,tmpK0,len); + } + + } else { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("breaking: out of cut"); + } + // Checkpoint output: + if (period_for_output > 0) + if (((int)floor(sim_time / time_step) % period_for_output == 0) && + (len > ia_params->affinity_r0)) { + FILE *fp; + double tmpPon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + fp = fopen("affinity_check.dat", "a"); + fprintf(fp, "sim_time %f, period_for_output %d aff type: %d ", + sim_time, period_for_output, aff_type_extracted); + fprintf(fp, "Pon %f, Kon %f, particle %d, Poff = %f, F = %f, " + "Koff = %f, K0 = %f, len = %f \n", + tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff, + tmpF, tmpKoff, tmpK0, len); + fclose(fp); + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + double Pon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + // The probability is given by function Pon(x)= 1 - e^(-x) where x is + // Kon*dt. Here is a table of values of this function, just to have an + // idea about the values + // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | + // 1.5 | 2.0 | 3.0 | + // 5.0 + // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | + // 0.77 | 0.84 | 0.95 | 0.99 + double decide = d_random(); + if (decide < + Pon) { // the bond will be created only with probability Pon. + // printf("Creating: Pon = %f, decide = %f", Pon, decide); + double folded_pos[3]; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + // printf("d: %f %f %f\n",d[0],d[1],d[2]); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } else { + // printf("In range, not creating: Pon = %f, decide = %f", Pon, + // decide); + } + } + } + } } - if ( aff_type_extracted == 4 ) { - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintaind the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * - * comments: - * strength of the force is proportional to the actual bond length - * bond is created with probability 1-exp(-Kon*timestep) - * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake the bond - * Koff depends on the bondlength via Koff = K0*exp(F/Fd) = K0*exp(kappa*r/Fd) - * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. - * here, maxBond is used as detachment force F_d. The original check for ensuring, that partice flows out of the cut-off radius and the bond remains active is replaced with fixed check, that bond length must not be greater that 0.8 cut_off - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - fac = ia_params->affinity_kappa*len; - //double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j] / len; - } - // Decision whether I should break the bond: - // First, force exerted on bond is stored in fac - double tmpF = fac; - // Then, zero force off rate K_0 is stored at ia_params_Koff - double tmpK0 = ia_params->affinity_Koff; - // Then, detachment force is stored in ia_params->affinity_maxBond - double tmpFd = ia_params->affinity_maxBond; - // Then, compute Koff - double tmpKoff = tmpK0*exp( tmpF / tmpFd); - // Finally, compute Poff - double Poff = 1.0 - exp( - tmpKoff*time_step); - //printf("%f ", Poff); - if (len < 0.8*ia_params->affinity_cut) { // in other implementation, maxBond is used here. However, in this implementation, we need maxBond for setting detachment force F_d - double decide = d_random(); - if ( decide < Poff ) - { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; -// printf("bond broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",Poff,tmpF,tmpKoff,tmpK0,len); - } - - } else { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - //printf("breaking: out of cut"); - } - // Checkpoint output: - if (period_for_output > 0 ) if ((int)floor(sim_time/time_step) % period_for_output == 0 ) { - FILE *fp; - double tmpPon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - fp = fopen("affinity_check.dat","a"); - fprintf(fp,"sim_time %f, period_for_output %d aff type: %d ",sim_time,period_for_output,aff_type_extracted); - fprintf(fp,"Pon %f, Kon %f, particle %d, Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff,tmpF,tmpKoff,tmpK0,len); - fclose(fp); - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - double Pon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - // The probability is given by function Pon(x)= 1 - e^(-x) where x is Kon*dt. Here is a table of values of this function, just to have an idea about the values - // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.5 | 2.0 | 3.0 | 5.0 - // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | 0.77 | 0.84 | 0.95 | 0.99 - double decide = d_random(); - if ( decide < Pon ) - { // the bond will be created only with probability Pon. - //printf("Creating: Pon = %f, decide = %f", Pon, decide); - double folded_pos[3]; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } else { - //printf("In range, not creating: Pon = %f, decide = %f", Pon, decide); - } - } - } - } - } - if ( aff_type_extracted == 5 ) { //second implementation of affinity - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintaind the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * - * comments: - * strength of the force is proportiona to the difference of actual bond length and 75% of the relaxed bond length - * bond is created with probability 1-exp(-Kon*timestep) - * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake the bond - * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = K0*exp(kappa(r-0.75*r0)/Fd) - * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. - * here, maxBond is used as detachment force F_d. The original check for ensuring, that partice flows out of the cut-off radius and the bond remains active is replaced with fixed check, that bond length must not be greater that 0.8 cut_off - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - if (len > 0.75*(ia_params->affinity_r0)) { - fac = ia_params->affinity_kappa*(len - 0.75*(ia_params->affinity_r0)); - //printf("len %f r0 %f\n",len, ia_params->affinity_r0); - } - else fac = 0.0; - //double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j] / len; -// ftemp += abs(fac * vec[j] / len); - } - //if (ftemp > 0.000000000000001) printf("%f ",fac); - // Decision whether I should break the bond: - // First, force exerted on bond is stored in fac - double tmpF = fac; - // Then, zero force off rate K_0 is stored at ia_params_Koff - double tmpK0 = ia_params->affinity_Koff; - // Then, detachment force is stored in ia_params->affinity_maxBond - double tmpFd = ia_params->affinity_maxBond; - // Then, compute Koff - double tmpKoff = tmpK0*exp( tmpF / tmpFd); - // Finally, compute Poff - double Poff = 1.0 - exp( - tmpKoff*time_step); - //printf("%f ", Poff); - if (len < 0.8*ia_params->affinity_cut) { // in other implementation, maxBond is used here. However, in this implementation, we need maxBond for setting detachment force F_d - double decide = d_random(); - if ( decide < Poff ) - { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; -// printf("bond broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",Poff,tmpF,tmpKoff,tmpK0,len); - } - - } else { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - //printf("breaking: out of cut"); - } - // Checkpoint output: - if (period_for_output > 0 ) if (((int)floor(sim_time/time_step) % period_for_output == 0 ) && (len > ia_params->affinity_r0) ) { - FILE *fp; - double tmpPon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - fp = fopen("affinity_check.dat","a"); - fprintf(fp,"sim_time %f, period_for_output %d aff type: %d ",sim_time,period_for_output,aff_type_extracted); - fprintf(fp,"Pon %f, Kon %f, particle %d, Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff,tmpF,tmpKoff,tmpK0,len); - fclose(fp); - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - double Pon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - // The probability is given by function Pon(x)= 1 - e^(-x) where x is Kon*dt. Here is a table of values of this function, just to have an idea about the values - // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.5 | 2.0 | 3.0 | 5.0 - // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | 0.77 | 0.84 | 0.95 | 0.99 - double decide = d_random(); - if ( decide < Pon ) - { // the bond will be created only with probability Pon. - //printf("Creating: Pon = %f, decide = %f", Pon, decide); - double folded_pos[3]; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - //printf("d: %f %f %f\n",d[0],d[1],d[2]); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } else { - //printf("In range, not creating: Pon = %f, decide = %f", Pon, decide); - } - } - } - } - } - if ( aff_type_extracted == 6 ) { //second implementation of affinity - /************************ - * - * Here I can implement the affinity force. - * I have the position of the particle - p1, and under p1->p.bond_site I have the coordinate of the bond_site. - * Also, under d[3] I have the vector towards the constraint meaning that force on p1 should be in the direction of d[3]. - * - * Algorithm: - * 1. First check is whether I am in the cut-off radius: ?dist < affinity_cut?. - * 2. Then I check whether there exists a bond from the current particle: ?bond_site != -1? - * 3. If yes, then I maintaind the bond. I put the forces and afterwards I decide whether the bond will brake or not. - * 4. If no, I maintain the creation of a bond. First I check whether I am in the area of possible bond creation: ?dist < affinity_r0? - * 5. If yes, I run the decision algorithm for bond creation and I either create or does not create the bond. - * 6. If I am not in the area of possible bond creation I do nothing - * - * - * comments: - * strength of the force is proportiona to the difference of actual bond length and the relaxed bond length - * bond is created with probability 1-exp(-Kon*timestep) - * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake the bond - * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = K0*exp(kappa(r-0.75*r0)/Fd) - * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. - * here, maxBond is used as detachment force F_d. The original check for ensuring, that partice flows out of the cut-off radius and the bond remains active is replaced with fixed check, that bond length must not be greater that 0.8 cut_off - *********************/ - int j; - double fac=0.0; - if((dist < ia_params->affinity_cut)) { // Checking whether I am inside the interaction cut-off radius. - if(dist > 0.0) { - //printf("bond_site: %f %f %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); - if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists - { // Bond exists - double folded_pos[3], vec[3], len2, len; - int img[3]; - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - for(j=0;j<3;j++) - vec[j] = p1->p.bond_site[j] - unfolded_pos[j]; // Shouldn't be the vec vector normalized? Yes, but with affinity_r0 and not by len!!! - len2 = sqrlen(vec); - len = sqrt(len2); - if (len > 1.0*(ia_params->affinity_r0)) { - fac = ia_params->affinity_kappa*(len - 1.0*(ia_params->affinity_r0)); - //printf("len %f r0 %f\n",len, ia_params->affinity_r0); - } - else fac = 0.0; - //double ftemp = 0; - for(j=0;j<3;j++) - { - force[j] += fac * vec[j] / len; -// ftemp += abs(fac * vec[j] / len); - } - //if (ftemp > 0.000000000000001) printf("%f ",fac); - // Decision whether I should break the bond: - // First, force exerted on bond is stored in fac - double tmpF = fac; - // Then, zero force off rate K_0 is stored at ia_params_Koff - double tmpK0 = ia_params->affinity_Koff; - // Then, detachment force is stored in ia_params->affinity_maxBond - double tmpFd = ia_params->affinity_maxBond; - // Then, compute Koff - double tmpKoff = tmpK0*exp( tmpF / tmpFd); - // Finally, compute Poff - double Poff = 1.0 - exp( - tmpKoff*time_step); - //printf("%f ", Poff); - if (len < 0.8*ia_params->affinity_cut) { // in other implementation, maxBond is used here. However, in this implementation, we need maxBond for setting detachment force F_d - double decide = d_random(); - if ( decide < Poff ) - { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; -// printf("bond broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",Poff,tmpF,tmpKoff,tmpK0,len); - } - - } else { - for(j=0;j<3;j++) p1->p.bond_site[j] = -1; - //printf("breaking: out of cut"); - } - // Checkpoint output: - if (period_for_output > 0 ) if (((int)floor(sim_time/time_step) % period_for_output == 0 ) && (len > ia_params->affinity_r0) ) { - FILE *fp; - double tmpPon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - fp = fopen("affinity_check.dat","a"); - fprintf(fp,"sim_time %f, period_for_output %d aff type: %d ",sim_time,period_for_output,aff_type_extracted); - fprintf(fp,"Pon %f, Kon %f, particle %d, Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f \n",tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff,tmpF,tmpKoff,tmpK0,len); - fclose(fp); - } - } - else if (dist < ia_params->affinity_r0) - { // Bond does not exist, we are inside of possible bond creation area, lets talk about creating a bond - double Pon = 1.0 - exp( - ia_params->affinity_Kon*time_step); - // The probability is given by function Pon(x)= 1 - e^(-x) where x is Kon*dt. Here is a table of values of this function, just to have an idea about the values - // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | 1.5 | 2.0 | 3.0 | 5.0 - // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | 0.77 | 0.84 | 0.95 | 0.99 - double decide = d_random(); - if ( decide < Pon ) - { // the bond will be created only with probability Pon. - //printf("Creating: Pon = %f, decide = %f", Pon, decide); - /* fold the coordinates of the particle */ - Vector3d unfolded_pos=unfolded_position(p1); - //printf("folded positions: %f %f %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); - //printf("d: %f %f %f\n",d[0],d[1],d[2]); - for(j=0;j<3;j++) - p1->p.bond_site[j] = unfolded_pos[j] - d[j]; - } else { - //printf("In range, not creating: Pon = %f, decide = %f", Pon, decide); - } - } - } - } - } + if (aff_type_extracted == 3) { + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintaind the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * + * comments: + * strength of the force is proportiona to the difference of actual bond + *length and relaxed bond length + * bond is created with probability 1-exp(-Kon*timestep) + * bond is ruptured with probability 1-exp(-Koff*timestep) to brake the + *bond + * Koff is given as parameter, is not dependent on the force nor the bond + *length + * here, maxBond stands for ensuring, that partice flows out of the + *cut-off radius and the bond remains active. maxBond should be always less + *than cut_off radius + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + if (len > ia_params->affinity_r0) { + fac = ia_params->affinity_kappa * (len - ia_params->affinity_r0) / + len; + // printf("len %f r0 %f\n",len, ia_params->affinity_r0); + } else + fac = 0.0; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j]; + } + // printf("%f ",ftemp); + // Decision whether I should break the bond: + // The random decision algorithm is much more complicated with Fd + // detachment force etc. Here, I use much simpler rule, the same as + // with Kon, except that the probability of bond breakage increases + // with prolongation of the bond. If the bond reaches -} + double Poff = 1.0 - exp(-ia_params->affinity_Koff * time_step); + if (len < ia_params->affinity_maxBond) { + double decide = d_random(); + if (decide < Poff) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + } + + } else { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("breaking: out of cut"); + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + double Pon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + // The probability is given by function Pon(x)= 1 - e^(-x) where x is + // Kon*dt. Here is a table of values of this function, just to have an + // idea about the values + // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | + // 1.5 | 2.0 | 3.0 | + // 5.0 + // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | + // 0.77 | 0.84 | 0.95 | 0.99 + double decide = d_random(); + if (decide < + Pon) { // the bond will be created only with probability Pon. + // printf("Creating: Pon = %f, decide = %f", Pon, decide); + double folded_pos[3]; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + // printf("d: %f %f %f\n",d[0],d[1],d[2]); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } else { + // printf("In range, not creating: Pon = %f, decide = %f", Pon, + // decide); + } + } + } + } + } + if (aff_type_extracted == 4) { + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintaind the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * + * comments: + * strength of the force is proportional to the actual bond length + * bond is created with probability 1-exp(-Kon*timestep) + * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake + *the bond + * Koff depends on the bondlength via Koff = K0*exp(F/Fd) = + *K0*exp(kappa*r/Fd) + * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. + * here, maxBond is used as detachment force F_d. The original check for + *ensuring, that partice flows out of the cut-off radius and the bond remains + *active is replaced with fixed check, that bond length must not be greater + *that 0.8 cut_off + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + fac = ia_params->affinity_kappa * len; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j] / len; + } + // Decision whether I should break the bond: + // First, force exerted on bond is stored in fac + double tmpF = fac; + // Then, zero force off rate K_0 is stored at ia_params_Koff + double tmpK0 = ia_params->affinity_Koff; + // Then, detachment force is stored in ia_params->affinity_maxBond + double tmpFd = ia_params->affinity_maxBond; + // Then, compute Koff + double tmpKoff = tmpK0 * exp(tmpF / tmpFd); + // Finally, compute Poff + double Poff = 1.0 - exp(-tmpKoff * time_step); + // printf("%f ", Poff); + if (len < 0.8 * ia_params->affinity_cut) { // in other implementation, + // maxBond is used here. + // However, in this + // implementation, we need + // maxBond for setting + // detachment force F_d + double decide = d_random(); + if (decide < Poff) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("bond + //broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f + //\n",Poff,tmpF,tmpKoff,tmpK0,len); + } + } else { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("breaking: out of cut"); + } + // Checkpoint output: + if (period_for_output > 0) + if ((int)floor(sim_time / time_step) % period_for_output == 0) { + FILE *fp; + double tmpPon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + fp = fopen("affinity_check.dat", "a"); + fprintf(fp, "sim_time %f, period_for_output %d aff type: %d ", + sim_time, period_for_output, aff_type_extracted); + fprintf(fp, "Pon %f, Kon %f, particle %d, Poff = %f, F = %f, " + "Koff = %f, K0 = %f, len = %f \n", + tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff, + tmpF, tmpKoff, tmpK0, len); + fclose(fp); + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + double Pon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + // The probability is given by function Pon(x)= 1 - e^(-x) where x is + // Kon*dt. Here is a table of values of this function, just to have an + // idea about the values + // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | + // 1.5 | 2.0 | 3.0 | + // 5.0 + // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | + // 0.77 | 0.84 | 0.95 | 0.99 + double decide = d_random(); + if (decide < + Pon) { // the bond will be created only with probability Pon. + // printf("Creating: Pon = %f, decide = %f", Pon, decide); + double folded_pos[3]; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } else { + // printf("In range, not creating: Pon = %f, decide = %f", Pon, + // decide); + } + } + } + } + } + if (aff_type_extracted == 5) { // second implementation of affinity + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintaind the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * + * comments: + * strength of the force is proportiona to the difference of actual bond + *length and 75% of the relaxed bond length + * bond is created with probability 1-exp(-Kon*timestep) + * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake + *the bond + * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = + *K0*exp(kappa(r-0.75*r0)/Fd) + * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. + * here, maxBond is used as detachment force F_d. The original check for + *ensuring, that partice flows out of the cut-off radius and the bond remains + *active is replaced with fixed check, that bond length must not be greater + *that 0.8 cut_off + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + if (len > 0.75 * (ia_params->affinity_r0)) { + fac = ia_params->affinity_kappa * + (len - 0.75 * (ia_params->affinity_r0)); + // printf("len %f r0 %f\n",len, ia_params->affinity_r0); + } else + fac = 0.0; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j] / len; + // ftemp += abs(fac * vec[j] / + //len); + } + // if (ftemp > 0.000000000000001) printf("%f ",fac); + // Decision whether I should break the bond: + // First, force exerted on bond is stored in fac + double tmpF = fac; + // Then, zero force off rate K_0 is stored at ia_params_Koff + double tmpK0 = ia_params->affinity_Koff; + // Then, detachment force is stored in ia_params->affinity_maxBond + double tmpFd = ia_params->affinity_maxBond; + // Then, compute Koff + double tmpKoff = tmpK0 * exp(tmpF / tmpFd); + // Finally, compute Poff + double Poff = 1.0 - exp(-tmpKoff * time_step); + // printf("%f ", Poff); + if (len < 0.8 * ia_params->affinity_cut) { // in other implementation, + // maxBond is used here. + // However, in this + // implementation, we need + // maxBond for setting + // detachment force F_d + double decide = d_random(); + if (decide < Poff) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("bond + //broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f + //\n",Poff,tmpF,tmpKoff,tmpK0,len); + } + + } else { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("breaking: out of cut"); + } + // Checkpoint output: + if (period_for_output > 0) + if (((int)floor(sim_time / time_step) % period_for_output == 0) && + (len > ia_params->affinity_r0)) { + FILE *fp; + double tmpPon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + fp = fopen("affinity_check.dat", "a"); + fprintf(fp, "sim_time %f, period_for_output %d aff type: %d ", + sim_time, period_for_output, aff_type_extracted); + fprintf(fp, "Pon %f, Kon %f, particle %d, Poff = %f, F = %f, " + "Koff = %f, K0 = %f, len = %f \n", + tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff, + tmpF, tmpKoff, tmpK0, len); + fclose(fp); + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + double Pon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + // The probability is given by function Pon(x)= 1 - e^(-x) where x is + // Kon*dt. Here is a table of values of this function, just to have an + // idea about the values + // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | + // 1.5 | 2.0 | 3.0 | + // 5.0 + // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | + // 0.77 | 0.84 | 0.95 | 0.99 + double decide = d_random(); + if (decide < + Pon) { // the bond will be created only with probability Pon. + // printf("Creating: Pon = %f, decide = %f", Pon, decide); + double folded_pos[3]; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + // printf("d: %f %f %f\n",d[0],d[1],d[2]); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } else { + // printf("In range, not creating: Pon = %f, decide = %f", Pon, + // decide); + } + } + } + } + } + if (aff_type_extracted == 6) { // second implementation of affinity + /************************ + * + * Here I can implement the affinity force. + * I have the position of the particle - p1, and under p1->p.bond_site I have + *the coordinate of the bond_site. + * Also, under d[3] I have the vector towards the constraint meaning that + *force on p1 should be in the direction of d[3]. + * + * Algorithm: + * 1. First check is whether I am in the cut-off radius: ?dist < + *affinity_cut?. + * 2. Then I check whether there exists a bond from the current particle: + *?bond_site != -1? + * 3. If yes, then I maintaind the bond. I put the forces and afterwards I + *decide whether the bond will brake or not. + * 4. If no, I maintain the creation of a bond. First I check whether I am in + *the area of possible bond creation: ?dist < affinity_r0? + * 5. If yes, I run the decision algorithm for bond creation and I either + *create or does not create the bond. + * 6. If I am not in the area of possible bond creation I do nothing + * + * + * comments: + * strength of the force is proportiona to the difference of actual bond + *length and the relaxed bond length + * bond is created with probability 1-exp(-Kon*timestep) + * maxBond is not used, we use probability 1-exp(-Koff*timestep) to brake + *the bond + * Koff depends on the bondlenth via Koff = K0*exp(F/Fd) = + *K0*exp(kappa(r-0.75*r0)/Fd) + * here, ia_params->Koff gives us K_0, off rate when bond is relaxed. + * here, maxBond is used as detachment force F_d. The original check for + *ensuring, that partice flows out of the cut-off radius and the bond remains + *active is replaced with fixed check, that bond length must not be greater + *that 0.8 cut_off + *********************/ + int j; + double fac = 0.0; + if ((dist < ia_params->affinity_cut)) { // Checking whether I am inside the + // interaction cut-off radius. + if (dist > 0.0) { + // printf("bond_site: %f %f + // %f\n",p1->p.bond_site[0],p1->p.bond_site[1],p1->p.bond_site[2]); + if ((p1->p.bond_site[0] >= 0) && (p1->p.bond_site[1] >= 0) && + (p1->p.bond_site[2] >= 0)) // Checking whether any bond exists + { // Bond exists + double folded_pos[3], vec[3], len2, len; + int img[3]; + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + for (j = 0; j < 3; j++) + vec[j] = p1->p.bond_site[j] - + unfolded_pos[j]; // Shouldn't be the vec vector normalized? + // Yes, but with affinity_r0 and not by + // len!!! + len2 = sqrlen(vec); + len = sqrt(len2); + if (len > 1.0 * (ia_params->affinity_r0)) { + fac = ia_params->affinity_kappa * + (len - 1.0 * (ia_params->affinity_r0)); + // printf("len %f r0 %f\n",len, ia_params->affinity_r0); + } else + fac = 0.0; + // double ftemp = 0; + for (j = 0; j < 3; j++) { + force[j] += fac * vec[j] / len; + // ftemp += abs(fac * vec[j] / + //len); + } + // if (ftemp > 0.000000000000001) printf("%f ",fac); + // Decision whether I should break the bond: + // First, force exerted on bond is stored in fac + double tmpF = fac; + // Then, zero force off rate K_0 is stored at ia_params_Koff + double tmpK0 = ia_params->affinity_Koff; + // Then, detachment force is stored in ia_params->affinity_maxBond + double tmpFd = ia_params->affinity_maxBond; + // Then, compute Koff + double tmpKoff = tmpK0 * exp(tmpF / tmpFd); + // Finally, compute Poff + double Poff = 1.0 - exp(-tmpKoff * time_step); + // printf("%f ", Poff); + if (len < 0.8 * ia_params->affinity_cut) { // in other implementation, + // maxBond is used here. + // However, in this + // implementation, we need + // maxBond for setting + // detachment force F_d + double decide = d_random(); + if (decide < Poff) { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("bond + //broken. Poff = %f, F = %f, Koff = %f, K0 = %f, len = %f + //\n",Poff,tmpF,tmpKoff,tmpK0,len); + } + } else { + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = -1; + // printf("breaking: out of cut"); + } + // Checkpoint output: + if (period_for_output > 0) + if (((int)floor(sim_time / time_step) % period_for_output == 0) && + (len > ia_params->affinity_r0)) { + FILE *fp; + double tmpPon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + fp = fopen("affinity_check.dat", "a"); + fprintf(fp, "sim_time %f, period_for_output %d aff type: %d ", + sim_time, period_for_output, aff_type_extracted); + fprintf(fp, "Pon %f, Kon %f, particle %d, Poff = %f, F = %f, " + "Koff = %f, K0 = %f, len = %f \n", + tmpPon, ia_params->affinity_Kon, p1->p.identity, Poff, + tmpF, tmpKoff, tmpK0, len); + fclose(fp); + } + } else if (dist < ia_params->affinity_r0) { // Bond does not exist, we + // are inside of possible + // bond creation area, lets + // talk about creating a + // bond + double Pon = 1.0 - exp(-ia_params->affinity_Kon * time_step); + // The probability is given by function Pon(x)= 1 - e^(-x) where x is + // Kon*dt. Here is a table of values of this function, just to have an + // idea about the values + // x | 0 | 0.25 | 0.5 | 0.75 | 1.0 | + // 1.5 | 2.0 | 3.0 | + // 5.0 + // Pon(x) | 0 | 0.22 | 0.39 | 0.52 | 0.63 | + // 0.77 | 0.84 | 0.95 | 0.99 + double decide = d_random(); + if (decide < + Pon) { // the bond will be created only with probability Pon. + // printf("Creating: Pon = %f, decide = %f", Pon, decide); + /* fold the coordinates of the particle */ + Vector3d unfolded_pos = unfolded_position(p1); + // printf("folded positions: %f %f + // %f\n",folded_pos[0],folded_pos[1],folded_pos[2]); + // printf("d: %f %f %f\n",d[0],d[1],d[2]); + for (j = 0; j < 3; j++) + p1->p.bond_site[j] = unfolded_pos[j] - d[j]; + } else { + // printf("In range, not creating: Pon = %f, decide = %f", Pon, + // decide); + } + } + } + } + } +} #endif /* ifdef AFFINITY */ #endif diff --git a/src/core/object-in-fluid/membrane_collision.cpp b/src/core/object-in-fluid/membrane_collision.cpp index 600a5b3f68..f8aac6fc06 100644 --- a/src/core/object-in-fluid/membrane_collision.cpp +++ b/src/core/object-in-fluid/membrane_collision.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file membrane_collision.cpp * @@ -24,22 +24,22 @@ */ #include "membrane_collision.hpp" #include "../communication.hpp" -#include "interaction_data.hpp" +#include "interaction_data.hpp" #ifdef MEMBRANE_COLLISION -int membrane_collision_set_params(int part_type_a, int part_type_b, - double a, double n, double cut, double offset) -{ +int membrane_collision_set_params(int part_type_a, int part_type_b, double a, + double n, double cut, double offset) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; data->membrane_a = a; data->membrane_n = n; data->membrane_cut = cut; data->membrane_offset = offset; - + /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); @@ -47,5 +47,3 @@ int membrane_collision_set_params(int part_type_a, int part_type_b, } #endif - - diff --git a/src/core/object-in-fluid/membrane_collision.hpp b/src/core/object-in-fluid/membrane_collision.hpp index e0bf5519bd..4319646803 100644 --- a/src/core/object-in-fluid/membrane_collision.hpp +++ b/src/core/object-in-fluid/membrane_collision.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef MEMBRANE_COLLISION_H #define MEMBRANE_COLLISION_H @@ -31,79 +31,90 @@ #ifdef MEMBRANE_COLLISION +#include "../grid.hpp" +#include "../integrate.hpp" #include "../interaction_data.hpp" #include "../particle_data.hpp" -#include "../integrate.hpp" #include "../random.hpp" -#include "../grid.hpp" -int membrane_collision_set_params(int part_type_a, int part_type_b, - double a, double n, double cut, double offset); +int membrane_collision_set_params(int part_type_a, int part_type_b, double a, + double n, double cut, double offset); /** Resultant force due to a sigmoid potential between two // particles at interatomic separation r */ -inline double sigmoid_force_r(double a, double n, double r ) -{ - return (a/(1+exp(n*r))); +inline double sigmoid_force_r(double a, double n, double r) { + return (a / (1 + exp(n * r))); } /** Calculate membrane-collision force between particle p1 and p2 */ -inline void add_membrane_collision_pair_force(const Particle *p1, const Particle *p2, IA_parameters *ia_params, - double d[3], double dist, double force[3]) -{ - /************************ - * - * Description of implementation: - * We have two particles, each belongs to the membrane of a different immersed object - * For both particles we have the position of the particle - p, and in part->p.out_direction are the coordinates of the outward normal vector (with respect to the immersed object). - * - * Algorithm: - * 1) compute angle between outward normal vectors out1 and out2 to check if they are almost collinear (in this case nothing happens, this is at the edge of contact zone and forces should not be applied because they would quite likely have wrong direction) - * 2) in other cases, repulsive forces are applied in the direction out1-out2 - * - *********************/ - - int j; - double r_off, fac=0.0, product, angle, ndir; - Vector3d out1,out2,dir; - - if((dist < ia_params->membrane_cut+ia_params->membrane_offset)) { - - r_off = dist - ia_params->membrane_offset; - // offset needs to be checked for the unphysical case when r_off should be negative - - if(r_off > 0.0) { - - out1 = p1->p.out_direction; - out2 = p2->p.out_direction; - // check whether out_direction was set - if ( fabs(out1[0]) + fabs(out1[1]) + fabs(out1[2]) + fabs(out2[0]) + fabs(out2[1]) + fabs(out2[2]) < SMALL_OIF_MEMBRANE_CUTOFF) - { - fprintf(stderr, "membrane_collision.hpp: out_direction is not set. Probably, you have not used switch \" normal\" in your oif_create_template command. Exiting the process. \n"); - errexit(); - } - - // this is the direction in which the repulsive forces will be applied and its norm - dir=out1-out2; - ndir=dir.norm(); - - // for very small angles the force should not be applied - these happen at the crossing of the boundary and would result in oscillation - product = out1.dot(out2); - angle = acos(product); - - if (fabs(angle)>SMALL_OIF_MEMBRANE_CUTOFF){ - fac = sigmoid_force_r(ia_params->membrane_a, ia_params->membrane_n, r_off)/dist; - for(j=0;j<3;j++) - force[j] -= fac * dir[j]/ndir; - } - } - } -} +inline void add_membrane_collision_pair_force(const Particle *p1, + const Particle *p2, + IA_parameters *ia_params, + double d[3], double dist, + double force[3]) { + /************************ + * + * Description of implementation: +* We have two particles, each belongs to the membrane of a different immersed +*object + * For both particles we have the position of the particle - p, and in +*part->p.out_direction are the coordinates of the outward normal vector (with +*respect to the immersed object). +* + * Algorithm: + * 1) compute angle between outward normal vectors out1 and out2 to check if +*they are almost collinear (in this case nothing happens, this is at the edge of +*contact zone and forces should not be applied because they would quite likely +*have wrong direction) +* 2) in other cases, repulsive forces are applied in the direction out1-out2 +* +*********************/ + int j; + double r_off, fac = 0.0, product, angle, ndir; + Vector3d out1, out2, dir; + if ((dist < ia_params->membrane_cut + ia_params->membrane_offset)) { -#endif /* ifdef MEMBRANE_COLLISION */ -#endif + r_off = dist - ia_params->membrane_offset; + // offset needs to be checked for the unphysical case when r_off should be + // negative + + if (r_off > 0.0) { + out1 = p1->p.out_direction; + out2 = p2->p.out_direction; + // check whether out_direction was set + if (fabs(out1[0]) + fabs(out1[1]) + fabs(out1[2]) + fabs(out2[0]) + + fabs(out2[1]) + fabs(out2[2]) < + SMALL_OIF_MEMBRANE_CUTOFF) { + fprintf(stderr, "membrane_collision.hpp: out_direction is not set. " + "Probably, you have not used switch \" normal\" in " + "your oif_create_template command. Exiting the " + "process. \n"); + errexit(); + } + // this is the direction in which the repulsive forces will be applied and + // its norm + dir = out1 - out2; + ndir = dir.norm(); + // for very small angles the force should not be applied - these happen at + // the crossing of the boundary and would result in oscillation + product = out1.dot(out2); + angle = acos(product); + + if (fabs(angle) > SMALL_OIF_MEMBRANE_CUTOFF) { + fac = sigmoid_force_r(ia_params->membrane_a, ia_params->membrane_n, + r_off) / + dist; + for (j = 0; j < 3; j++) + force[j] -= fac * dir[j] / ndir; + } + } + } +} + +#endif /* ifdef MEMBRANE_COLLISION */ +#endif diff --git a/src/core/object-in-fluid/oif_global_forces.cpp b/src/core/object-in-fluid/oif_global_forces.cpp index 828a4bb322..db5cc398ef 100644 --- a/src/core/object-in-fluid/oif_global_forces.cpp +++ b/src/core/object-in-fluid/oif_global_forces.cpp @@ -111,24 +111,24 @@ void calc_oif_global(double *area_volume, // if(n_partners>2){ p3 = local_particles[p1->bl.e[j++]]; if (!p3) { - runtimeErrorMsg() - << "oif global calc: bond broken between particles " - << p1->p.identity << ", " << p1->bl.e[j - 2] << " and " - << p1->bl.e[j - 1] << " (particles not stored on the same node - " - "oif_global_forces1); n " - << p1->bl.n << " max " << p1->bl.max; + runtimeErrorMsg() << "oif global calc: bond broken between particles " + << p1->p.identity << ", " << p1->bl.e[j - 2] + << " and " << p1->bl.e[j - 1] + << " (particles not stored on the same node - " + "oif_global_forces1); n " + << p1->bl.n << " max " << p1->bl.max; return; } -// remaining neighbors fetched + // remaining neighbors fetched -// getting unfolded positions of all particles + // getting unfolded positions of all particles // first find out which particle out of p1, p2 (possibly p3, p4) is not // a ghost particle. In almost all cases it is p1, however, it might be // other one. we call this particle reference particle. if (p1->l.ghost != 1) { // unfold non-ghost particle using image, because for physical // particles, the structure p->l.i is correctly set - p11=unfolded_position(p1); + p11 = unfolded_position(p1); // other coordinates are obtained from its relative positions to the // reference particle get_mi_vector(AA, p2->r.p, p11); @@ -140,7 +140,7 @@ void calc_oif_global(double *area_volume, } else { // in case the first particle is a ghost particle if (p2->l.ghost != 1) { - p22=unfolded_position(p2); + p22 = unfolded_position(p2); get_mi_vector(AA, p1->r.p, p22); get_mi_vector(BB, p3->r.p, p22); for (int i = 0; i < 3; i++) { @@ -150,7 +150,7 @@ void calc_oif_global(double *area_volume, } else { // in case the first and the second particle are ghost particles if (p3->l.ghost != 1) { - p33=unfolded_position(p3); + p33 = unfolded_position(p3); get_mi_vector(AA, p1->r.p, p33); get_mi_vector(BB, p2->r.p, p33); for (int i = 0; i < 3; i++) { @@ -194,8 +194,8 @@ void add_oif_global_forces(double *area_volume, double VOL_force[3]; double VOL_A, VOL_norm[3], VOL_dn, VOL_vv; - double m1[3],m2[3],m3[3]; - double m1_length,m2_length,m3_length,t,fac; + double m1[3], m2[3], m3[3]; + double m1_length, m2_length, m3_length, t, fac; double deltaA, force1[3], force2[3], force3[3], rh[3], hn, h[3]; int k; @@ -247,14 +247,14 @@ void add_oif_global_forces(double *area_volume, return; } -// getting unfolded positions of all particles + // getting unfolded positions of all particles // first find out which particle out of p1, p2 (possibly p3, p4) is not // a ghost particle. In almost all cases it is p1, however, it might be // other one. we call this particle reference particle. if (p1->l.ghost != 1) { // unfold non-ghost particle using image, because for physical // particles, the structure p->l.i is correctly set - p11=unfolded_position(*p1); + p11 = unfolded_position(*p1); // other coordinates are obtained from its relative positions to the // reference particle get_mi_vector(AA, p2->r.p, p11); @@ -266,7 +266,7 @@ void add_oif_global_forces(double *area_volume, } else { // in case the first particle is a ghost particle if (p2->l.ghost != 1) { - p22 =unfolded_position(p2); + p22 = unfolded_position(p2); get_mi_vector(AA, p1->r.p, p22); get_mi_vector(BB, p3->r.p, p22); for (int i = 0; i < 3; i++) { @@ -276,7 +276,7 @@ void add_oif_global_forces(double *area_volume, } else { // in case the first and the second particle are ghost particles if (p3->l.ghost != 1) { - p33=unfolded_position(p3); + p33 = unfolded_position(p3); get_mi_vector(AA, p1->r.p, p33); get_mi_vector(BB, p2->r.p, p33); for (int i = 0; i < 3; i++) { @@ -292,58 +292,59 @@ void add_oif_global_forces(double *area_volume, } } - - // unfolded positions correct /// starting code from volume force - get_n_triangle(p11,p22,p33,VOL_norm); - VOL_dn=normr(VOL_norm); - VOL_A=area_triangle(p11,p22,p33); - VOL_vv=(VOL_volume - iaparams->p.oif_global_forces.V0)/iaparams->p.oif_global_forces.V0; - for(k=0;k<3;k++) { - VOL_force[k]=iaparams->p.oif_global_forces.kv * VOL_vv * VOL_A * VOL_norm[k]/VOL_dn * 1.0 / 3.0; - p1->f.f[k] += VOL_force[k]; + get_n_triangle(p11, p22, p33, VOL_norm); + VOL_dn = normr(VOL_norm); + VOL_A = area_triangle(p11, p22, p33); + VOL_vv = (VOL_volume - iaparams->p.oif_global_forces.V0) / + iaparams->p.oif_global_forces.V0; + for (k = 0; k < 3; k++) { + VOL_force[k] = iaparams->p.oif_global_forces.kv * VOL_vv * VOL_A * + VOL_norm[k] / VOL_dn * 1.0 / 3.0; + p1->f.f[k] += VOL_force[k]; p2->f.f[k] += VOL_force[k]; p3->f.f[k] += VOL_force[k]; } /// ending code from volume force - for(k=0;k<3;k++){ - h[k]=1.0/3.0 *(p11[k]+p22[k]+p33[k]); + for (k = 0; k < 3; k++) { + h[k] = 1.0 / 3.0 * (p11[k] + p22[k] + p33[k]); } - deltaA = (area - iaparams->p.oif_global_forces.A0_g)/iaparams->p.oif_global_forces.A0_g; - vecsub(h,p11,m1); - vecsub(h,p22,m2); - vecsub(h,p33,m3); - + deltaA = (area - iaparams->p.oif_global_forces.A0_g) / + iaparams->p.oif_global_forces.A0_g; + vecsub(h, p11, m1); + vecsub(h, p22, m2); + vecsub(h, p33, m3); + m1_length = normr(m1); m2_length = normr(m2); m3_length = normr(m3); - - fac = iaparams->p.oif_global_forces.ka_g*VOL_A * deltaA/(m1_length*m1_length + m2_length*m2_length + m3_length*m3_length); - - for(k=0; k<3; k++) { // local area force for p1 - force1[k] = fac*m1[k]; - } - for(k=0; k<3; k++) { // local area force for p2 - force2[k] = fac*m2[k]; + + fac = iaparams->p.oif_global_forces.ka_g * VOL_A * deltaA / + (m1_length * m1_length + m2_length * m2_length + + m3_length * m3_length); + + for (k = 0; k < 3; k++) { // local area force for p1 + force1[k] = fac * m1[k]; + } + for (k = 0; k < 3; k++) { // local area force for p2 + force2[k] = fac * m2[k]; + } + for (k = 0; k < 3; k++) { // local area force for p3 + force3[k] = fac * m3[k]; } - for(k=0; k<3; k++) { // local area force for p3 - force3[k] = fac*m3[k]; - } - for(k=0;k<3;k++) { - p1->f.f[k] += force1[k]; + for (k = 0; k < 3; k++) { + p1->f.f[k] += force1[k]; p2->f.f[k] += force2[k]; p3->f.f[k] += force3[k]; } - } - else{ - j+=n_partners; + } else { + j += n_partners; } } } } - -int max_oif_objects=0; +int max_oif_objects = 0; diff --git a/src/core/object-in-fluid/oif_local_forces.cpp b/src/core/object-in-fluid/oif_local_forces.cpp index b2340d6d2d..6c8b9b4fdc 100755 --- a/src/core/object-in-fluid/oif_local_forces.cpp +++ b/src/core/object-in-fluid/oif_local_forces.cpp @@ -1,40 +1,43 @@ /* Copyright (C) 2012,2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file oif_local_forces.hpp * Routines to calculate the OIF_LOCAL_FORCES - * for a particle quadruple (two neighboring triangles with common edge). (Dupin2007) + * for a particle quadruple (two neighboring triangles with common edge). + * (Dupin2007) * \ref forces.cpp */ -#include "communication.hpp" #include "oif_local_forces.hpp" +#include "communication.hpp" /** set parameters for the OIF_LOCAL_FORCES potential.*/ -int oif_local_forces_set_params(int bond_type, double r0, double ks, double kslin, double phi0, double kb, double A01, double A02, double kal, double kvisc) -{ - if(bond_type < 0) +int oif_local_forces_set_params(int bond_type, double r0, double ks, + double kslin, double phi0, double kb, + double A01, double A02, double kal, + double kvisc) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); - + bonded_ia_params[bond_type].p.oif_local_forces.phi0 = phi0; bonded_ia_params[bond_type].p.oif_local_forces.kb = kb; bonded_ia_params[bond_type].p.oif_local_forces.r0 = r0; @@ -44,12 +47,11 @@ int oif_local_forces_set_params(int bond_type, double r0, double ks, double ksli bonded_ia_params[bond_type].p.oif_local_forces.A02 = A02; bonded_ia_params[bond_type].p.oif_local_forces.kal = kal; bonded_ia_params[bond_type].p.oif_local_forces.kvisc = kvisc; - + bonded_ia_params[bond_type].type = BONDED_IA_OIF_LOCAL_FORCES; - bonded_ia_params[bond_type].num = 3; + bonded_ia_params[bond_type].num = 3; - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } - diff --git a/src/core/object-in-fluid/oif_local_forces.hpp b/src/core/object-in-fluid/oif_local_forces.hpp index 312b168d38..6136d0a584 100755 --- a/src/core/object-in-fluid/oif_local_forces.hpp +++ b/src/core/object-in-fluid/oif_local_forces.hpp @@ -1,289 +1,314 @@ /* Copyright (C) 2012,2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _OBJECT_IN_FLUID_OIF_LOCAL_FORCES_H #define _OBJECT_IN_FLUID_OIF_LOCAL_FORCES_H /** \file oif_local_forces.hpp * Routines to calculate the OIF_LOCAL_FORCES - * for a particle quadruple (two neighboring triangles with common edge). (Dupin2007) + * for a particle quadruple (two neighboring triangles with common edge). + * (Dupin2007) * \ref forces.cpp */ -#include "utils.hpp" -#include "interaction_data.hpp" -#include "particle_data.hpp" -#include "grid.hpp" #include "config.hpp" +#include "grid.hpp" #include "integrate.hpp" +#include "interaction_data.hpp" +#include "particle_data.hpp" +#include "utils.hpp" // set parameters for local forces -int oif_local_forces_set_params(int bond_type, double r0, double ks, double kslin, double phi0, double kb, double A01, double A02, double kal, double kvisc); +int oif_local_forces_set_params(int bond_type, double r0, double ks, + double kslin, double phi0, double kb, + double A01, double A02, double kal, + double kvisc); -inline double KS(double lambda){ // Defined by (19) from Dupin2007 - double res; - res = (pow(lambda,0.5) + pow(lambda,-2.5))/(lambda + pow(lambda,-3.)); - return res; +inline double KS(double lambda) { // Defined by (19) from Dupin2007 + double res; + res = (pow(lambda, 0.5) + pow(lambda, -2.5)) / (lambda + pow(lambda, -3.)); + return res; } /** Computes the local forces (Dupin2007) and adds them - to the particle forces. + to the particle forces. @param p1,p2,p3 Pointers to particles of triangle 1. @param p2,p3,p4 Pointers to particles of triangle 2. (triangles have particles p2 and p3 in common) @return 0 */ -inline int calc_oif_local(Particle *p2, Particle *p1, Particle *p3, Particle *p4, - Bonded_ia_parameters *iaparams, double force[3], - double force2[3], double force3[3], double force4[3])// first-fold-then-the-same approach +inline int calc_oif_local(Particle *p2, Particle *p1, Particle *p3, + Particle *p4, Bonded_ia_parameters *iaparams, + double force[3], double force2[3], double force3[3], + double force4[3]) // first-fold-then-the-same approach { - int i, img[3]; - Vector3d fp1,fp2,fp3,fp4; - double AA[3],BB[3],CC[3]; - double n1[3],n2[3],dn1,dn2,phi,aa; - double dx[3],fac,dr,len2,len,lambda; - double A,h[3],rh[3],hn; - double m1[3],m2[3],m3[3]; - double v[3], def_vel; - double m1_length,m2_length,m3_length,t; - - // first find out which particle out of p1, p2 (possibly p3, p4) is not a ghost particle. In almost all cases it is p2, however, it might be other one. we call this particle reference particle. - if (p2->l.ghost != 1) { - //unfold non-ghost particle using image, because for physical particles, the structure p->l.i is correctly set - fp2=unfolded_position(*p2); - // other coordinates are obtained from its relative positions to the reference particle - get_mi_vector(AA, p1->r.p, fp2); - get_mi_vector(BB, p3->r.p, fp2); - get_mi_vector(CC, p4->r.p, fp2); - for (i=0; i<3; i++) { - fp1[i] = fp2[i] + AA[i]; - fp3[i] = fp2[i] + BB[i]; - fp4[i] = fp2[i] + CC[i]; + int i, img[3]; + Vector3d fp1, fp2, fp3, fp4; + double AA[3], BB[3], CC[3]; + double n1[3], n2[3], dn1, dn2, phi, aa; + double dx[3], fac, dr, len2, len, lambda; + double A, h[3], rh[3], hn; + double m1[3], m2[3], m3[3]; + double v[3], def_vel; + double m1_length, m2_length, m3_length, t; + + // first find out which particle out of p1, p2 (possibly p3, p4) is not a + // ghost particle. In almost all cases it is p2, however, it might be other + // one. we call this particle reference particle. + if (p2->l.ghost != 1) { + // unfold non-ghost particle using image, because for physical particles, + // the structure p->l.i is correctly set + fp2 = unfolded_position(*p2); + // other coordinates are obtained from its relative positions to the + // reference particle + get_mi_vector(AA, p1->r.p, fp2); + get_mi_vector(BB, p3->r.p, fp2); + get_mi_vector(CC, p4->r.p, fp2); + for (i = 0; i < 3; i++) { + fp1[i] = fp2[i] + AA[i]; + fp3[i] = fp2[i] + BB[i]; + fp4[i] = fp2[i] + CC[i]; + } + } else { + // in case particle p2 is a ghost particle + if (p1->l.ghost != 1) { + fp1 = unfolded_position(*p1); + get_mi_vector(AA, p2->r.p, fp1); + get_mi_vector(BB, p3->r.p, fp1); + get_mi_vector(CC, p4->r.p, fp1); + for (i = 0; i < 3; i++) { + fp2[i] = fp1[i] + AA[i]; + fp3[i] = fp1[i] + BB[i]; + fp4[i] = fp1[i] + CC[i]; + } + } else { + // in case the first and the second particle are ghost particles + if (p3->l.ghost != 1) { + fp3 = unfolded_position(p3); + get_mi_vector(AA, p1->r.p, fp3); + get_mi_vector(BB, p2->r.p, fp3); + get_mi_vector(CC, p4->r.p, fp3); + for (i = 0; i < 3; i++) { + fp1[i] = fp3[i] + AA[i]; + fp2[i] = fp3[i] + BB[i]; + fp4[i] = fp3[i] + CC[i]; + } + } else { + // in case the first and the second particle are ghost particles + if (p4->l.ghost != 1) { + fp4 = unfolded_position(p4); + get_mi_vector(AA, p1->r.p, fp4); + get_mi_vector(BB, p2->r.p, fp4); + get_mi_vector(CC, p3->r.p, fp4); + for (i = 0; i < 3; i++) { + fp1[i] = fp4[i] + AA[i]; + fp2[i] = fp4[i] + BB[i]; + fp3[i] = fp4[i] + CC[i]; + } + } else { + throw std::runtime_error("Something wrong in oif_local_forces.hpp: " + "All particles in a bond are ghost " + "particles, impossible to unfold the " + "positions...\n"); + return 0; } - } else { - // in case particle p2 is a ghost particle - if (p1->l.ghost != 1) { - fp1=unfolded_position(*p1); - get_mi_vector(AA, p2->r.p, fp1); - get_mi_vector(BB, p3->r.p, fp1); - get_mi_vector(CC, p4->r.p, fp1); - for (i=0; i<3; i++) { - fp2[i] = fp1[i] + AA[i]; - fp3[i] = fp1[i] + BB[i]; - fp4[i] = fp1[i] + CC[i]; - } - } else { - // in case the first and the second particle are ghost particles - if (p3->l.ghost != 1) { - fp3=unfolded_position(p3); - get_mi_vector(AA, p1->r.p, fp3); - get_mi_vector(BB, p2->r.p, fp3); - get_mi_vector(CC, p4->r.p, fp3); - for (i=0; i<3; i++) { - fp1[i] = fp3[i] + AA[i]; - fp2[i] = fp3[i] + BB[i]; - fp4[i] = fp3[i] + CC[i]; - } - } else { - // in case the first and the second particle are ghost particles - if (p4->l.ghost != 1) { - fp4=unfolded_position(p4); - get_mi_vector(AA, p1->r.p, fp4); - get_mi_vector(BB, p2->r.p, fp4); - get_mi_vector(CC, p3->r.p, fp4); - for (i=0; i<3; i++) { - fp1[i] = fp4[i] + AA[i]; - fp2[i] = fp4[i] + BB[i]; - fp3[i] = fp4[i] + CC[i]; - } - } else { - throw std::runtime_error("Something wrong in oif_local_forces.hpp: All particles in a bond are ghost particles, impossible to unfold the positions...\n"); - return 0; - } - } - } - } - - for(i=0; i<3; i++) { - force[i] = 0; - force2[i] = 0; - force3[i] = 0; - force4[i] = 0; + } } + } - // non-linear stretching - if (iaparams->p.oif_local_forces.ks > TINY_OIF_ELASTICITY_COEFFICIENT) { - vecsub(fp2,fp3,dx); - len2 = sqrlen(dx); - len = sqrt(len2); - dr = len - iaparams->p.oif_local_forces.r0; - lambda = 1.0*len/iaparams->p.oif_local_forces.r0; - fac = -iaparams->p.oif_local_forces.ks * KS(lambda) * dr; // no normalization - for(i=0; i<3; i++) { - force2[i] += fac*dx[i]/len; - force3[i] += -fac*dx[i]/len; - } + for (i = 0; i < 3; i++) { + force[i] = 0; + force2[i] = 0; + force3[i] = 0; + force4[i] = 0; + } + + // non-linear stretching + if (iaparams->p.oif_local_forces.ks > TINY_OIF_ELASTICITY_COEFFICIENT) { + vecsub(fp2, fp3, dx); + len2 = sqrlen(dx); + len = sqrt(len2); + dr = len - iaparams->p.oif_local_forces.r0; + lambda = 1.0 * len / iaparams->p.oif_local_forces.r0; + fac = + -iaparams->p.oif_local_forces.ks * KS(lambda) * dr; // no normalization + for (i = 0; i < 3; i++) { + force2[i] += fac * dx[i] / len; + force3[i] += -fac * dx[i] / len; } - - // linear stretching - if (iaparams->p.oif_local_forces.kslin > TINY_OIF_ELASTICITY_COEFFICIENT) { - vecsub(fp2,fp3,dx); - len2 = sqrlen(dx); - len = sqrt(len2); - dr = len - iaparams->p.oif_local_forces.r0; - fac = -iaparams->p.oif_local_forces.kslin * dr; // no normalization - for(i=0; i<3; i++) { - force2[i] += fac*dx[i]/len; - force3[i] += -fac*dx[i]/len; - } + } + + // linear stretching + if (iaparams->p.oif_local_forces.kslin > TINY_OIF_ELASTICITY_COEFFICIENT) { + vecsub(fp2, fp3, dx); + len2 = sqrlen(dx); + len = sqrt(len2); + dr = len - iaparams->p.oif_local_forces.r0; + fac = -iaparams->p.oif_local_forces.kslin * dr; // no normalization + for (i = 0; i < 3; i++) { + force2[i] += fac * dx[i] / len; + force3[i] += -fac * dx[i] / len; } - - // viscous force - if (iaparams->p.oif_local_forces.kvisc > TINY_OIF_ELASTICITY_COEFFICIENT) { // to be implemented.... - - vecsub(fp2,fp3,dx); - len2 = sqrlen(dx); - len = sqrt(len2); - - v[0] = (p3->m.v[0] - p2->m.v[0]); - v[1] = (p3->m.v[1] - p2->m.v[1]); - v[2] = (p3->m.v[2] - p2->m.v[2]); - - // Variant A - // Here the force is in the direction of relative velocity btw points - - // Code: - //for(i=0;i<3;i++) { - //force2[i] += iaparams->p.oif_local_forces.kvisc*v[i]; - //force3[i] -= iaparams->p.oif_local_forces.kvisc*v[i]; - //} - - // Variant B - // Here the force is the projection of relative velocity btw points onto line btw the points - - // denote p vector between p2 and p3 - // denote v the velocity difference between the points p2 and p3 - // denote alpha the angle between p and v - // denote x the projevted v onto p - // cos alpha = |x|/|v| - // cos alpha = (v,p)/(|v||p|) - // together we get |x|=(v,p)/|p| - // also, x is along p, so x = |x|.p/|p| - // so x = p/|p| . (v,p)/|p| - // altogether x = p . (v,p)/(|p|)^2 - // |p|^2 is stored in len2 - - // Code: - def_vel = dx[0]*v[0] + dx[1]*v[1] + dx[2]*v[2]; - fac = iaparams->p.oif_local_forces.kvisc*def_vel/len2; - for(i=0;i<3;i++) { - force2[i] += fac*dx[i]; - force3[i] -= fac*dx[i]; - } + } + + // viscous force + if (iaparams->p.oif_local_forces.kvisc > + TINY_OIF_ELASTICITY_COEFFICIENT) { // to be implemented.... + + vecsub(fp2, fp3, dx); + len2 = sqrlen(dx); + len = sqrt(len2); + + v[0] = (p3->m.v[0] - p2->m.v[0]); + v[1] = (p3->m.v[1] - p2->m.v[1]); + v[2] = (p3->m.v[2] - p2->m.v[2]); + + // Variant A + // Here the force is in the direction of relative velocity btw points + + // Code: + // for(i=0;i<3;i++) { + // force2[i] += iaparams->p.oif_local_forces.kvisc*v[i]; + // force3[i] -= iaparams->p.oif_local_forces.kvisc*v[i]; + //} + + // Variant B + // Here the force is the projection of relative velocity btw points onto + // line btw the points + + // denote p vector between p2 and p3 + // denote v the velocity difference between the points p2 and p3 + // denote alpha the angle between p and v + // denote x the projevted v onto p + // cos alpha = |x|/|v| + // cos alpha = (v,p)/(|v||p|) + // together we get |x|=(v,p)/|p| + // also, x is along p, so x = |x|.p/|p| + // so x = p/|p| . (v,p)/|p| + // altogether x = p . (v,p)/(|p|)^2 + // |p|^2 is stored in len2 + + // Code: + def_vel = dx[0] * v[0] + dx[1] * v[1] + dx[2] * v[2]; + fac = iaparams->p.oif_local_forces.kvisc * def_vel / len2; + for (i = 0; i < 3; i++) { + force2[i] += fac * dx[i]; + force3[i] -= fac * dx[i]; } - - /* bending - forceT1 is restoring force for triangle p1,p2,p3 and force2T restoring force for triangle p2,p3,p4 - p1 += forceT1; p2 -= 0.5*forceT1+0.5*forceT2; p3 -= 0.5*forceT1+0.5*forceT2; p4 += forceT2; */ - if (iaparams->p.oif_local_forces.kb > TINY_OIF_ELASTICITY_COEFFICIENT) { - get_n_triangle(fp2,fp1,fp3,n1); - dn1=normr(n1); - get_n_triangle(fp2,fp3,fp4,n2); - dn2=normr(n2); - phi = angle_btw_triangles(fp1,fp2,fp3,fp4); - - aa = (phi - iaparams->p.oif_local_forces.phi0); // no renormalization by phi0, to be consistent with Krueger and Fedosov - fac = iaparams->p.oif_local_forces.kb * aa; - for(i=0; i<3; i++) { - force[i] += fac * n1[i]/dn1; - force2[i] -= (0.5 * fac * n1[i]/dn1 + 0.5 * fac * n2[i]/dn2); - force3[i] -= (0.5 * fac * n1[i]/dn1 + 0.5 * fac * n2[i]/dn2); - force4[i] += fac * n2[i]/dn2; - } + } + + /* bending + forceT1 is restoring force for triangle p1,p2,p3 and force2T restoring + force for triangle p2,p3,p4 + p1 += forceT1; p2 -= 0.5*forceT1+0.5*forceT2; p3 -= + 0.5*forceT1+0.5*forceT2; p4 += forceT2; */ + if (iaparams->p.oif_local_forces.kb > TINY_OIF_ELASTICITY_COEFFICIENT) { + get_n_triangle(fp2, fp1, fp3, n1); + dn1 = normr(n1); + get_n_triangle(fp2, fp3, fp4, n2); + dn2 = normr(n2); + phi = angle_btw_triangles(fp1, fp2, fp3, fp4); + + aa = (phi - iaparams->p.oif_local_forces.phi0); // no renormalization by + // phi0, to be consistent + // with Krueger and Fedosov + fac = iaparams->p.oif_local_forces.kb * aa; + for (i = 0; i < 3; i++) { + force[i] += fac * n1[i] / dn1; + force2[i] -= (0.5 * fac * n1[i] / dn1 + 0.5 * fac * n2[i] / dn2); + force3[i] -= (0.5 * fac * n1[i] / dn1 + 0.5 * fac * n2[i] / dn2); + force4[i] += fac * n2[i] / dn2; } + } - /* local area - for both triangles - only 1/3 of calculated forces are added, because each triangle will enter this calculation 3 times (one time per edge) - - Proportional distribution of forces, implemented according to the article - I.Jancigova, I.Cimrak, - Non-uniform force allocation for area preservation in spring network models, - International Journal for Numerical Methods in Biomedical Engineering, DOI: 10.1002/cnm.2757 - - */ - if (iaparams->p.oif_local_forces.kal > TINY_OIF_ELASTICITY_COEFFICIENT) { - - // triangle p1,p2,p3 - for(i=0; i<3; i++){ // centroid of triangle p1,p2,p3 - h[i]=1.0/3.0 *(fp1[i]+fp2[i]+fp3[i]); - } - A=area_triangle(fp1,fp2,fp3); - t = sqrt(A/iaparams->p.oif_local_forces.A01) - 1.0; - vecsub(h,fp1,m1); - vecsub(h,fp2,m2); - vecsub(h,fp3,m3); - - m1_length = normr(m1); - m2_length = normr(m2); - m3_length = normr(m3); - - fac = iaparams->p.oif_local_forces.kal*iaparams->p.oif_local_forces.A01*(2*t+t*t)/(m1_length*m1_length + m2_length*m2_length + m3_length*m3_length); - - for(i=0; i<3; i++) { // local area force for p1 - force[i] += fac*m1[i]/3.0; - } - for(i=0; i<3; i++) { // local area force for p2 - force2[i] += fac*m2[i]/3.0; - } - for(i=0; i<3; i++) { // local area force for p3 - force3[i] += fac*m3[i]/3.0; - } - - // triangle p2,p3,p4 - for(i=0; i<3; i++) { // centroid of triangle p2,p3,p4 - h[i]=1.0/3.0 *(fp2[i]+fp3[i]+fp4[i]); - } - A=area_triangle(fp2,fp3,fp4); - t = sqrt(A/iaparams->p.oif_local_forces.A02) - 1.0; //// - vecsub(h,fp2,m1); - vecsub(h,fp3,m2); - vecsub(h,fp4,m3); - - m1_length = normr(m1); - m2_length = normr(m2); - m3_length = normr(m3); - - fac = iaparams->p.oif_local_forces.kal*iaparams->p.oif_local_forces.A02*(2*t+t*t)/(m1_length*m1_length + m2_length*m2_length + m3_length*m3_length); - - for(i=0; i<3; i++) { // local area force for p2 - force2[i] += fac*m1[i]/3.0; - } - for(i=0; i<3; i++) { // local area force for p3 - force3[i] += fac*m2[i]/3.0; - } - for(i=0; i<3; i++) { // local area force for p4 - force4[i] += fac*m3[i]/3.0; - } + /* local area + for both triangles + only 1/3 of calculated forces are added, because each triangle will enter + this calculation 3 times (one time per edge) + + Proportional distribution of forces, implemented according to the + article + I.Jancigova, I.Cimrak, + Non-uniform force allocation for area preservation in spring + network models, + International Journal for Numerical Methods in Biomedical + Engineering, DOI: 10.1002/cnm.2757 + + */ + if (iaparams->p.oif_local_forces.kal > TINY_OIF_ELASTICITY_COEFFICIENT) { + + // triangle p1,p2,p3 + for (i = 0; i < 3; i++) { // centroid of triangle p1,p2,p3 + h[i] = 1.0 / 3.0 * (fp1[i] + fp2[i] + fp3[i]); + } + A = area_triangle(fp1, fp2, fp3); + t = sqrt(A / iaparams->p.oif_local_forces.A01) - 1.0; + vecsub(h, fp1, m1); + vecsub(h, fp2, m2); + vecsub(h, fp3, m3); + + m1_length = normr(m1); + m2_length = normr(m2); + m3_length = normr(m3); + fac = iaparams->p.oif_local_forces.kal * iaparams->p.oif_local_forces.A01 * + (2 * t + t * t) / (m1_length * m1_length + m2_length * m2_length + + m3_length * m3_length); + + for (i = 0; i < 3; i++) { // local area force for p1 + force[i] += fac * m1[i] / 3.0; + } + for (i = 0; i < 3; i++) { // local area force for p2 + force2[i] += fac * m2[i] / 3.0; + } + for (i = 0; i < 3; i++) { // local area force for p3 + force3[i] += fac * m3[i] / 3.0; + } + + // triangle p2,p3,p4 + for (i = 0; i < 3; i++) { // centroid of triangle p2,p3,p4 + h[i] = 1.0 / 3.0 * (fp2[i] + fp3[i] + fp4[i]); + } + A = area_triangle(fp2, fp3, fp4); + t = sqrt(A / iaparams->p.oif_local_forces.A02) - 1.0; //// + vecsub(h, fp2, m1); + vecsub(h, fp3, m2); + vecsub(h, fp4, m3); + + m1_length = normr(m1); + m2_length = normr(m2); + m3_length = normr(m3); + + fac = iaparams->p.oif_local_forces.kal * iaparams->p.oif_local_forces.A02 * + (2 * t + t * t) / (m1_length * m1_length + m2_length * m2_length + + m3_length * m3_length); + + for (i = 0; i < 3; i++) { // local area force for p2 + force2[i] += fac * m1[i] / 3.0; } + for (i = 0; i < 3; i++) { // local area force for p3 + force3[i] += fac * m2[i] / 3.0; + } + for (i = 0; i < 3; i++) { // local area force for p4 + force4[i] += fac * m3[i] / 3.0; + } + } return 0; } #endif - diff --git a/src/core/object-in-fluid/out_direction.cpp b/src/core/object-in-fluid/out_direction.cpp index 28c78aff50..e9ca8991d1 100644 --- a/src/core/object-in-fluid/out_direction.cpp +++ b/src/core/object-in-fluid/out_direction.cpp @@ -1,43 +1,44 @@ /* Copyright (C) 2012,2013,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -/** \file out_direction.hpp Routines to calculate the outward direction of the membrane - * using a particle quadruple (one particle and its 3 strategically placed neighbors) +/** \file out_direction.hpp Routines to calculate the outward direction of the + * membrane + * using a particle quadruple (one particle and its 3 strategically placed + * neighbors) */ -#include "../communication.hpp" #include "out_direction.hpp" +#include "../communication.hpp" #ifdef MEMBRANE_COLLISION // set out_direction parameters -int oif_out_direction_set_params(int bond_type) -{ - if(bond_type < 0) +int oif_out_direction_set_params(int bond_type) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); bonded_ia_params[bond_type].type = BONDED_IA_OIF_OUT_DIRECTION; - bonded_ia_params[bond_type].num = 3; + bonded_ia_params[bond_type].num = 3; - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/object-in-fluid/out_direction.hpp b/src/core/object-in-fluid/out_direction.hpp index 17f257b9a1..5b1a02bc54 100644 --- a/src/core/object-in-fluid/out_direction.hpp +++ b/src/core/object-in-fluid/out_direction.hpp @@ -1,106 +1,134 @@ /* Copyright (C) 2012,2013,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _OBJECT_IN_FLUID_OUT_DIRECTION_H #define _OBJECT_IN_FLUID_OUT_DIRECTION_H -/** \file out_direction.hpp Routines to calculate the outward direction of the membrane - * using a particle quadruple (one particle and its 3 strategically placed neighbors) +/** \file out_direction.hpp Routines to calculate the outward direction of the + * membrane + * using a particle quadruple (one particle and its 3 strategically placed + * neighbors) */ #include "config.hpp" #ifdef MEMBRANE_COLLISION -#include "utils.hpp" +#include "grid.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" -#include "grid.hpp" +#include "utils.hpp" // set out_direction parameters int oif_out_direction_set_params(int bond_type); -/** Computes the outward direction of the membrane from one particle and its three neighbors - +/** Computes the outward direction of the membrane from one particle and its + three neighbors + @param p1 Pointer to the central particle. @param p2,p3,p4 Pointers to the neighboring particles. computes the normal of triangle p2p3p4 - this triangle was initially oriented in such a way that its normal already points out of the object + this triangle was initially oriented in such a way that its normal already + points out of the object normalizes and stores the result as out_direction in p1 data @return 0 */ -inline int calc_out_direction(Particle *p1, Particle *p2, Particle *p3, Particle *p4, - Bonded_ia_parameters *iaparams)// first-fold-then-the-same approach -{ - double n[3],dn; - int j; - Vector3d fp1, fp2, fp3, fp4; - double AA[3],BB[3],CC[3]; +inline int calc_out_direction( + Particle *p1, Particle *p2, Particle *p3, Particle *p4, + Bonded_ia_parameters *iaparams) // first-fold-then-the-same approach +{ + double n[3], dn; + int j; + Vector3d fp1, fp2, fp3, fp4; + double AA[3], BB[3], CC[3]; - // first find out which particle out of p1, p2 (possibly p3, p4) is not a ghost particle. In almost all cases it is p2, however, it might be other one. we call this particle reference particle. - if (p2->l.ghost != 1) { - //unfold non-ghost particle using image, because for physical particles, the structure p->l.i is correctly set - fp2=unfolded_position(p2); - // other coordinates are obtained from its relative positions to the reference particle - get_mi_vector(AA, p1->r.p, fp2); - get_mi_vector(BB, p3->r.p, fp2); - get_mi_vector(CC, p4->r.p, fp2); - for (int i=0; i < 3; i++) { fp1[i] = fp2[i] + AA[i]; fp3[i] = fp2[i] + BB[i]; fp4[i] = fp2[i] + CC[i]; } + // first find out which particle out of p1, p2 (possibly p3, p4) is not a + // ghost particle. In almost all cases it is p2, however, it might be other + // one. we call this particle reference particle. + if (p2->l.ghost != 1) { + // unfold non-ghost particle using image, because for physical particles, + // the structure p->l.i is correctly set + fp2 = unfolded_position(p2); + // other coordinates are obtained from its relative positions to the + // reference particle + get_mi_vector(AA, p1->r.p, fp2); + get_mi_vector(BB, p3->r.p, fp2); + get_mi_vector(CC, p4->r.p, fp2); + for (int i = 0; i < 3; i++) { + fp1[i] = fp2[i] + AA[i]; + fp3[i] = fp2[i] + BB[i]; + fp4[i] = fp2[i] + CC[i]; + } + } else { + // in case particle p2 is a ghost particle + if (p1->l.ghost != 1) { + fp1 = unfolded_position(p1); + get_mi_vector(AA, p2->r.p, fp1); + get_mi_vector(BB, p3->r.p, fp1); + get_mi_vector(CC, p4->r.p, fp1); + for (int i = 0; i < 3; i++) { + fp2[i] = fp1[i] + AA[i]; + fp3[i] = fp1[i] + BB[i]; + fp4[i] = fp1[i] + CC[i]; + } } else { - // in case particle p2 is a ghost particle - if (p1->l.ghost != 1) { - fp1=unfolded_position(p1); - get_mi_vector(AA, p2->r.p, fp1); - get_mi_vector(BB, p3->r.p, fp1); - get_mi_vector(CC, p4->r.p, fp1); - for (int i=0; i < 3; i++) { fp2[i] = fp1[i] + AA[i]; fp3[i] = fp1[i] + BB[i]; fp4[i] = fp1[i] + CC[i];} + // in case the first and the second particle are ghost particles + if (p3->l.ghost != 1) { + fp3 = unfolded_position(p3); + get_mi_vector(AA, p1->r.p, fp3); + get_mi_vector(BB, p2->r.p, fp3); + get_mi_vector(CC, p4->r.p, fp3); + for (int i = 0; i < 3; i++) { + fp1[i] = fp3[i] + AA[i]; + fp2[i] = fp3[i] + BB[i]; + fp4[i] = fp3[i] + CC[i]; + } + } else { + // in case the first and the second particle are ghost particles + if (p4->l.ghost != 1) { + fp4 = unfolded_position(p4); + get_mi_vector(AA, p1->r.p, fp4); + get_mi_vector(BB, p2->r.p, fp4); + get_mi_vector(CC, p3->r.p, fp4); + for (int i = 0; i < 3; i++) { + fp1[i] = fp4[i] + AA[i]; + fp2[i] = fp4[i] + BB[i]; + fp3[i] = fp4[i] + CC[i]; + } } else { - // in case the first and the second particle are ghost particles - if (p3->l.ghost != 1) { - fp3=unfolded_position(p3); - get_mi_vector(AA, p1->r.p, fp3); - get_mi_vector(BB, p2->r.p, fp3); - get_mi_vector(CC, p4->r.p, fp3); - for (int i=0; i < 3; i++) { fp1[i] = fp3[i] + AA[i]; fp2[i] = fp3[i] + BB[i]; fp4[i] = fp3[i] + CC[i]; } - } else { - // in case the first and the second particle are ghost particles - if (p4->l.ghost != 1) { - fp4=unfolded_position(p4); - get_mi_vector(AA, p1->r.p, fp4); - get_mi_vector(BB, p2->r.p, fp4); - get_mi_vector(CC, p3->r.p, fp4); - for (int i=0; i < 3; i++) { fp1[i] = fp4[i] + AA[i]; fp2[i] = fp4[i] + BB[i]; fp3[i] = fp4[i] + CC[i]; } - } else { - printf("Something wrong in out_direction.hpp: All particles in a bond are ghost particles, impossible to unfold the positions..."); - return 0; - } - } + printf("Something wrong in out_direction.hpp: All particles in a " + "bond are ghost particles, impossible to unfold the " + "positions..."); + return 0; } + } } - - get_n_triangle(fp2,fp3,fp4,n); - dn=normr(n); - if ( fabs(dn) < 0.001 ) - printf("out_direction.hpp, calc_out_direction: Length of outward vector is close to zero!\n"); - for(j=0;j<3;j++){ - p1->p.out_direction[j] = n[j]/dn; - } - return 0; + } + + get_n_triangle(fp2, fp3, fp4, n); + dn = normr(n); + if (fabs(dn) < 0.001) + printf("out_direction.hpp, calc_out_direction: Length of outward vector is " + "close to zero!\n"); + for (j = 0; j < 3; j++) { + p1->p.out_direction[j] = n[j] / dn; + } + return 0; } #endif /* ifdef MEMBRANE_COLLISION */ diff --git a/src/core/observables/CylindricalLBFluxDensityProfileAtParticlePositions.cpp b/src/core/observables/CylindricalLBFluxDensityProfileAtParticlePositions.cpp index c6b6f9cf52..14730e6089 100644 --- a/src/core/observables/CylindricalLBFluxDensityProfileAtParticlePositions.cpp +++ b/src/core/observables/CylindricalLBFluxDensityProfileAtParticlePositions.cpp @@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "lb.hpp" #include "CylindricalLBFluxDensityProfileAtParticlePositions.hpp" +#include "lb.hpp" #include "lbgpu.hpp" #include "utils.hpp" #include "utils/Histogram.hpp" @@ -53,20 +53,18 @@ operator()(PartCfg &partCfg) const { if (lattice_switch & LATTICE_LB_GPU) { #if defined(LB_GPU) lb_lbfluid_get_interpolated_velocity_at_positions( - ppos.data(), velocities.data(), - ppos.size() / 3); + ppos.data(), velocities.data(), ppos.size() / 3); #endif } else if (lattice_switch & LATTICE_LB) { #if defined(LB) - for (size_t ind=0; ind < ppos.size(); ind +=3) { - Vector3d pos_tmp = {ppos[ind + 0], - ppos[ind + 1], - ppos[ind + 2]}; + for (size_t ind = 0; ind < ppos.size(); ind += 3) { + Vector3d pos_tmp = {ppos[ind + 0], ppos[ind + 1], ppos[ind + 2]}; lb_lbfluid_get_interpolated_velocity(pos_tmp, &(velocities[ind + 0])); } #endif } else { - throw std::runtime_error("Either CPU LB or GPU LB has to be active for this observables to work."); + throw std::runtime_error("Either CPU LB or GPU LB has to be active for " + "this observables to work."); } for (auto &p : folded_positions) p -= center; diff --git a/src/core/observables/CylindricalLBProfileObservable.hpp b/src/core/observables/CylindricalLBProfileObservable.hpp index 5780da53b7..fc011c7794 100644 --- a/src/core/observables/CylindricalLBProfileObservable.hpp +++ b/src/core/observables/CylindricalLBProfileObservable.hpp @@ -12,8 +12,8 @@ namespace Observables { -class CylindricalLBProfileObservable : public CylindricalProfileObservable, public LBObservable { -}; +class CylindricalLBProfileObservable : public CylindricalProfileObservable, + public LBObservable {}; } // Namespace Observables #endif diff --git a/src/core/observables/CylindricalLBVelocityProfile.cpp b/src/core/observables/CylindricalLBVelocityProfile.cpp index ed692c879b..eb77282ad9 100644 --- a/src/core/observables/CylindricalLBVelocityProfile.cpp +++ b/src/core/observables/CylindricalLBVelocityProfile.cpp @@ -18,8 +18,8 @@ along with this program. If not, see . */ -#include "lb.hpp" #include "CylindricalLBVelocityProfile.hpp" +#include "lb.hpp" #include "utils.hpp" #include "utils/Histogram.hpp" @@ -45,10 +45,10 @@ operator()(PartCfg &partCfg) const { #endif } else if (lattice_switch & LATTICE_LB) { #if defined(LB) - for (size_t ind=0; ind < m_sample_positions.size(); ind +=3) { + for (size_t ind = 0; ind < m_sample_positions.size(); ind += 3) { Vector3d pos_tmp = {m_sample_positions[ind + 0], - m_sample_positions[ind + 1], - m_sample_positions[ind + 2]}; + m_sample_positions[ind + 1], + m_sample_positions[ind + 2]}; lb_lbfluid_get_interpolated_velocity(pos_tmp, &(velocities[ind + 0])); } #endif diff --git a/src/core/observables/CylindricalLBVelocityProfileAtParticlePositions.cpp b/src/core/observables/CylindricalLBVelocityProfileAtParticlePositions.cpp index ad48e2e421..3b6f8b8fab 100644 --- a/src/core/observables/CylindricalLBVelocityProfileAtParticlePositions.cpp +++ b/src/core/observables/CylindricalLBVelocityProfileAtParticlePositions.cpp @@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "lb.hpp" #include "CylindricalLBVelocityProfileAtParticlePositions.hpp" +#include "lb.hpp" #include "lbgpu.hpp" #include "utils.hpp" #include "utils/Histogram.hpp" @@ -57,15 +57,14 @@ operator()(PartCfg &partCfg) const { #endif } else if (lattice_switch & LATTICE_LB) { #if defined(LB) - for (size_t ind=0; ind < ppos.size(); ind +=3) { - Vector3d pos_tmp = {ppos[ind + 0], - ppos[ind + 1], - ppos[ind + 2]}; + for (size_t ind = 0; ind < ppos.size(); ind += 3) { + Vector3d pos_tmp = {ppos[ind + 0], ppos[ind + 1], ppos[ind + 2]}; lb_lbfluid_get_interpolated_velocity(pos_tmp, &(velocities[ind + 0])); } #endif } else { - throw std::runtime_error("Either CPU LB or GPU LB has to be active for this observable to work."); + throw std::runtime_error("Either CPU LB or GPU LB has to be active for " + "this observable to work."); } for (auto &p : folded_positions) p -= center; diff --git a/src/core/observables/FluxDensityProfile.hpp b/src/core/observables/FluxDensityProfile.hpp index 94f6838414..2ac979cf90 100644 --- a/src/core/observables/FluxDensityProfile.hpp +++ b/src/core/observables/FluxDensityProfile.hpp @@ -21,10 +21,9 @@ class FluxDensityProfile : public PidProfileObservable { Utils::Histogram histogram(n_bins, 3, limits); for (auto const &id : ids()) { auto const ppos = ::Vector<3, double>(folded_position(partCfg[id])); - histogram.update(ppos, - ::Vector<3, double>{{partCfg[id].m.v[0], - partCfg[id].m.v[1], - partCfg[id].m.v[2]}}); + histogram.update( + ppos, ::Vector<3, double>{{partCfg[id].m.v[0], partCfg[id].m.v[1], + partCfg[id].m.v[2]}}); } histogram.normalize(); return histogram.get_histogram(); diff --git a/src/core/observables/ForceDensityProfile.hpp b/src/core/observables/ForceDensityProfile.hpp index c911d3a1db..11bfa7a22a 100644 --- a/src/core/observables/ForceDensityProfile.hpp +++ b/src/core/observables/ForceDensityProfile.hpp @@ -22,10 +22,9 @@ class ForceDensityProfile : public PidProfileObservable { Utils::Histogram histogram(n_bins, 3, limits); for (auto const &id : ids()) { auto const ppos = ::Vector<3, double>(folded_position(partCfg[id])); - histogram.update(ppos, - ::Vector<3, double>{{partCfg[id].f.f[0], - partCfg[id].f.f[1], - partCfg[id].f.f[2]}}); + histogram.update( + ppos, ::Vector<3, double>{{partCfg[id].f.f[0], partCfg[id].f.f[1], + partCfg[id].f.f[2]}}); } histogram.normalize(); return histogram.get_histogram(); diff --git a/src/core/observables/LBObservable.hpp b/src/core/observables/LBObservable.hpp index 565f150a66..46e34e0ad5 100644 --- a/src/core/observables/LBObservable.hpp +++ b/src/core/observables/LBObservable.hpp @@ -18,25 +18,26 @@ class LBObservable : virtual public Observable { if (sampling_delta_x == 0 or sampling_delta_y == 0 or sampling_delta_z == 0) throw std::runtime_error("Parameter delta_x/y/z must not be zero!"); const auto n_samples_x = static_cast( - std::rint((box_l[0] - sampling_offset_x) / sampling_delta_x)); + std::rint((box_l[0] - sampling_offset_x) / sampling_delta_x)); const auto n_samples_y = static_cast( - std::rint((box_l[1] - sampling_offset_y) / sampling_delta_y)); + std::rint((box_l[1] - sampling_offset_y) / sampling_delta_y)); const auto n_samples_z = static_cast( - std::rint((box_l[2] - sampling_offset_z) / sampling_delta_z)); + std::rint((box_l[2] - sampling_offset_z) / sampling_delta_z)); for (size_t x = 0; x < n_samples_x; ++x) { for (size_t y = 0; y < n_samples_y; ++y) { for (size_t z = 0; z < n_samples_z; ++z) { - m_sample_positions.push_back(sampling_offset_x + x * sampling_delta_x); - m_sample_positions.push_back(sampling_offset_y + y * sampling_delta_y); - m_sample_positions.push_back(sampling_offset_z + z * sampling_delta_z); + m_sample_positions.push_back(sampling_offset_x + + x * sampling_delta_x); + m_sample_positions.push_back(sampling_offset_y + + y * sampling_delta_y); + m_sample_positions.push_back(sampling_offset_z + + z * sampling_delta_z); } } - } + } } std::vector m_sample_positions; - }; - } #endif diff --git a/src/core/observables/LBProfileObservable.hpp b/src/core/observables/LBProfileObservable.hpp index d8152c4f04..6520d2ac0d 100644 --- a/src/core/observables/LBProfileObservable.hpp +++ b/src/core/observables/LBProfileObservable.hpp @@ -7,7 +7,6 @@ namespace Observables { class LBProfileObservable : public LBObservable, public ProfileObservable {}; - } #endif diff --git a/src/core/observables/LBVelocityProfile.cpp b/src/core/observables/LBVelocityProfile.cpp index 7a7e3fc601..a58e4953ab 100644 --- a/src/core/observables/LBVelocityProfile.cpp +++ b/src/core/observables/LBVelocityProfile.cpp @@ -1,11 +1,10 @@ +#include "LBVelocityProfile.hpp" #include "lb.hpp" #include "utils/Histogram.hpp" -#include "LBVelocityProfile.hpp" namespace Observables { -std::vector LBVelocityProfile:: -operator()(PartCfg &partCfg) const { +std::vector LBVelocityProfile::operator()(PartCfg &partCfg) const { std::array n_bins{{static_cast(n_x_bins), static_cast(n_y_bins), static_cast(n_z_bins)}}; @@ -24,19 +23,21 @@ operator()(PartCfg &partCfg) const { #endif } else if (lattice_switch & LATTICE_LB) { #if defined(LB) - for (size_t ind=0; ind < m_sample_positions.size(); ind +=3) { + for (size_t ind = 0; ind < m_sample_positions.size(); ind += 3) { Vector3d pos_tmp = {m_sample_positions[ind + 0], - m_sample_positions[ind + 1], - m_sample_positions[ind + 2]}; + m_sample_positions[ind + 1], + m_sample_positions[ind + 2]}; lb_lbfluid_get_interpolated_velocity(pos_tmp, &(velocities[ind + 0])); } #endif } else { - throw std::runtime_error("Either CPU LB or GPU LB has to be active for this observable to work."); + throw std::runtime_error("Either CPU LB or GPU LB has to be active for " + "this observable to work."); } for (size_t ind = 0; ind < m_sample_positions.size(); ind += 3) { - const Vector3d position = { - {m_sample_positions[ind + 0], m_sample_positions[ind + 1], m_sample_positions[ind + 2]}}; + const Vector3d position = {{m_sample_positions[ind + 0], + m_sample_positions[ind + 1], + m_sample_positions[ind + 2]}}; const Vector3d velocity = { {velocities[ind + 0], velocities[ind + 1], velocities[ind + 2]}}; histogram.update(position, velocity); @@ -45,7 +46,8 @@ operator()(PartCfg &partCfg) const { auto const tot_count = histogram.get_tot_count(); for (size_t ind = 0; ind < hist_tmp.size(); ++ind) { if (tot_count[ind] == 0 and not allow_empty_bins) { - auto const error = "Decrease sampling delta(s), bin " + std::to_string(ind) + " has no hit"; + auto const error = "Decrease sampling delta(s), bin " + + std::to_string(ind) + " has no hit"; throw std::runtime_error(error); } if (tot_count[ind] > 0) { @@ -54,5 +56,4 @@ operator()(PartCfg &partCfg) const { } return hist_tmp; } - } diff --git a/src/core/observables/not_yet_implemented/Average.hpp b/src/core/observables/not_yet_implemented/Average.hpp index 5cf7f84be2..7caad6b5fe 100644 --- a/src/core/observables/not_yet_implemented/Average.hpp +++ b/src/core/observables/not_yet_implemented/Average.hpp @@ -1,25 +1,26 @@ int ObservableAverage::actual_update() { - observable_average_container* data = (observable_average_container*) container; - data->n_sweeps++; - int error = data->reference_observable->calculate(); - if ( error != 0) - return 1; - double factor = 1 / (double) data->n_sweeps; - for (int i =0; ireference_observable->last_value[i]; - } - return 0; + observable_average_container *data = + (observable_average_container *)container; + data->n_sweeps++; + int error = data->reference_observable->calculate(); + if (error != 0) + return 1; + double factor = 1 / (double)data->n_sweeps; + for (int i = 0; i < n; i++) { + last_value[i] = (1 - factor) * last_value[i] + + factor * data->reference_observable->last_value[i]; + } + return 0; } int ObservableAverage::reset() { - observable_average_container* data = (observable_average_container*) container; - data->n_sweeps=0; - int error = data->reference_observable->calculate(); - for (int i =0; in_sweeps = 0; + int error = data->reference_observable->calculate(); + for (int i = 0; i < n; i++) { + last_value[i] = 0; + } + return error; } - - diff --git a/src/core/observables/not_yet_implemented/BlockedComForce.hpp b/src/core/observables/not_yet_implemented/BlockedComForce.hpp index 0b4a662a06..9345628d89 100644 --- a/src/core/observables/not_yet_implemented/BlockedComForce.hpp +++ b/src/core/observables/not_yet_implemented/BlockedComForce.hpp @@ -1,26 +1,26 @@ -int ObservableBlockedComForce::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableBlockedComForce::actual_calculate(PartCfg &partCfg) { + double *A = last_value; unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; - IntList* ids; + IntList *ids; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - ids=(IntList*) container; - n_blocks=n/3; - blocksize=ids->n/n_blocks; - for ( block = 0; block < n_blocks; block++ ) { - for ( i = 0; i < blocksize; i++ ) { - id = ids->e[block*blocksize+i]; + ids = (IntList *)container; + n_blocks = n / 3; + blocksize = ids->n / n_blocks; + for (block = 0; block < n_blocks; block++) { + for (i = 0; i < blocksize; i++) { + id = ids->e[block * blocksize + i]; if (ids->e[i] >= n_part) return 1; - A[3*block+0] += partCfg[id].f.f[0]/time_step/time_step*2; - A[3*block+1] += partCfg[id].f.f[1]/time_step/time_step*2; - A[3*block+2] += partCfg[id].f.f[2]/time_step/time_step*2; + A[3 * block + 0] += partCfg[id].f.f[0] / time_step / time_step * 2; + A[3 * block + 1] += partCfg[id].f.f[1] / time_step / time_step * 2; + A[3 * block + 2] += partCfg[id].f.f[2] / time_step / time_step * 2; } } return 0; diff --git a/src/core/observables/not_yet_implemented/BlockedComPosition.hpp b/src/core/observables/not_yet_implemented/BlockedComPosition.hpp index 09704f1f35..992b5d0d66 100644 --- a/src/core/observables/not_yet_implemented/BlockedComPosition.hpp +++ b/src/core/observables/not_yet_implemented/BlockedComPosition.hpp @@ -1,33 +1,33 @@ -int ObservableBlockedComPosition::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableBlockedComPosition::actual_calculate(PartCfg &partCfg) { + double *A = last_value; unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; double total_mass = 0; - IntList* ids; + IntList *ids; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - ids=(IntList*) container; - n_blocks=n/3; - blocksize=ids->n/n_blocks; - for ( block = 0; block < n_blocks; block++ ) { + ids = (IntList *)container; + n_blocks = n / 3; + blocksize = ids->n / n_blocks; + for (block = 0; block < n_blocks; block++) { total_mass = 0; - for ( i = 0; i < blocksize; i++ ) { - id = ids->e[block*blocksize+i]; + for (i = 0; i < blocksize; i++) { + id = ids->e[block * blocksize + i]; if (ids->e[i] >= n_part) return 1; - A[3*block+0] += (partCfg[id]).p.mass*partCfg[id].r.p[0]; - A[3*block+1] += (partCfg[id]).p.mass*partCfg[id].r.p[1]; - A[3*block+2] += (partCfg[id]).p.mass*partCfg[id].r.p[2]; + A[3 * block + 0] += (partCfg[id]).p.mass * partCfg[id].r.p[0]; + A[3 * block + 1] += (partCfg[id]).p.mass * partCfg[id].r.p[1]; + A[3 * block + 2] += (partCfg[id]).p.mass * partCfg[id].r.p[2]; total_mass += (partCfg[ids->e[i]]).p.mass; } - A[3*block+0] /= total_mass; - A[3*block+1] /= total_mass; - A[3*block+2] /= total_mass; + A[3 * block + 0] /= total_mass; + A[3 * block + 1] /= total_mass; + A[3 * block + 2] /= total_mass; } return 0; } diff --git a/src/core/observables/not_yet_implemented/BlockedComVelocity.hpp b/src/core/observables/not_yet_implemented/BlockedComVelocity.hpp index de3ff64960..57c16b2787 100644 --- a/src/core/observables/not_yet_implemented/BlockedComVelocity.hpp +++ b/src/core/observables/not_yet_implemented/BlockedComVelocity.hpp @@ -1,33 +1,33 @@ -int ObservableBlockedComVelocity::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableBlockedComVelocity::actual_calculate(PartCfg &partCfg) { + double *A = last_value; unsigned int i; unsigned int block; unsigned int n_blocks; unsigned int blocksize; unsigned int id; double total_mass = 0; - IntList* ids; + IntList *ids; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - ids=(IntList*) container; - n_blocks=n/3; - blocksize=ids->n/n_blocks; - for ( block = 0; block < n_blocks; block++ ) { + ids = (IntList *)container; + n_blocks = n / 3; + blocksize = ids->n / n_blocks; + for (block = 0; block < n_blocks; block++) { total_mass = 0; - for ( i = 0; i < blocksize; i++ ) { - id = ids->e[block*blocksize+i]; + for (i = 0; i < blocksize; i++) { + id = ids->e[block * blocksize + i]; if (ids->e[i] >= n_part) return 1; - A[3*block+0] += (partCfg[id]).p.mass*partCfg[id].m.v[0]/time_step; - A[3*block+1] += (partCfg[id]).p.mass*partCfg[id].m.v[1]/time_step; - A[3*block+2] += (partCfg[id]).p.mass*partCfg[id].m.v[2]/time_step; + A[3 * block + 0] += (partCfg[id]).p.mass * partCfg[id].m.v[0] / time_step; + A[3 * block + 1] += (partCfg[id]).p.mass * partCfg[id].m.v[1] / time_step; + A[3 * block + 2] += (partCfg[id]).p.mass * partCfg[id].m.v[2] / time_step; total_mass += (partCfg[ids->e[i]]).p.mass; } - A[3*block+0] /= total_mass; - A[3*block+1] /= total_mass; - A[3*block+2] /= total_mass; + A[3 * block + 0] /= total_mass; + A[3 * block + 1] /= total_mass; + A[3 * block + 2] /= total_mass; } return 0; } diff --git a/src/core/observables/not_yet_implemented/ComDipoleMoment.hpp b/src/core/observables/not_yet_implemented/ComDipoleMoment.hpp index d87da0eea5..aa2b9d2a82 100644 --- a/src/core/observables/not_yet_implemented/ComDipoleMoment.hpp +++ b/src/core/observables/not_yet_implemented/ComDipoleMoment.hpp @@ -1,23 +1,23 @@ #ifdef DIPOLES -int ObservableComDipoleMoment::actual_calculate(PartCfg & partCfg) { - double* A = last_value; - double d[3] = {0. , 0., 0. } ; - IntList* ids; +int ObservableComDipoleMoment::actual_calculate(PartCfg &partCfg) { + double *A = last_value; + double d[3] = {0., 0., 0.}; + IntList *ids; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - ids=(IntList*) container; - for (int i = 0; in; i++ ) { + ids = (IntList *)container; + for (int i = 0; i < ids->n; i++) { if (ids->e[i] > n_part) return 1; d[0] += partCfg[ids->e[i]].r.dip[0]; d[1] += partCfg[ids->e[i]].r.dip[1]; d[2] += partCfg[ids->e[i]].r.dip[2]; } - A[0]=d[0]; - A[1]=d[1]; - A[2]=d[2]; + A[0] = d[0]; + A[1] = d[1]; + A[2] = d[2]; return 0; } #endif diff --git a/src/core/observables/not_yet_implemented/InteractsWith.hpp b/src/core/observables/not_yet_implemented/InteractsWith.hpp index 69e3dbbb0c..caa7e83461 100644 --- a/src/core/observables/not_yet_implemented/InteractsWith.hpp +++ b/src/core/observables/not_yet_implemented/InteractsWith.hpp @@ -1,40 +1,40 @@ -int ObservableInteractsWith::actual_calculate(PartCfg & partCfg) { - double* A = last_value; - iw_params *params=(iw_params*) container; - IntList* ids1; - IntList* ids2; - int i,j; -// double dx,dy,dz; +int ObservableInteractsWith::actual_calculate(PartCfg &partCfg) { + double *A = last_value; + iw_params *params = (iw_params *)container; + IntList *ids1; + IntList *ids2; + int i, j; + // double dx,dy,dz; double dist2; - double cutoff2=params->cutoff*params->cutoff; + double cutoff2 = params->cutoff * params->cutoff; double pos1[3], pos2[3], dist[3]; - ids1=params->ids1; - ids2=params->ids2; + ids1 = params->ids1; + ids2 = params->ids2; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - for ( i = 0; in; i++ ) { + for (i = 0; i < ids1->n; i++) { if (ids1->e[i] >= n_part) return 1; - pos1[0]=partCfg[ids1->e[i]].r.p[0]; - pos1[1]=partCfg[ids1->e[i]].r.p[1]; - pos1[2]=partCfg[ids1->e[i]].r.p[2]; - for ( j = 0; jn; j++ ) { + pos1[0] = partCfg[ids1->e[i]].r.p[0]; + pos1[1] = partCfg[ids1->e[i]].r.p[1]; + pos1[2] = partCfg[ids1->e[i]].r.p[2]; + for (j = 0; j < ids2->n; j++) { if (ids2->e[j] >= n_part) return 1; if (ids2->e[j] == ids1->e[i]) // do not count self-interaction :-) continue; A[i] = 0; - pos2[0]=partCfg[ids2->e[j]].r.p[0]; - pos2[1]=partCfg[ids2->e[j]].r.p[1]; - pos2[2]=partCfg[ids2->e[j]].r.p[2]; - get_mi_vector(dist,pos1,pos2); - dist2= dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2]; - if(dist2e[j]].r.p[0]; + pos2[1] = partCfg[ids2->e[j]].r.p[1]; + pos2[2] = partCfg[ids2->e[j]].r.p[2]; + get_mi_vector(dist, pos1, pos2); + dist2 = dist[0] * dist[0] + dist[1] * dist[1] + dist[2] * dist[2]; + if (dist2 < cutoff2) { A[i] = 1; - break; - // interaction found for i, go for next + break; + // interaction found for i, go for next } } } diff --git a/src/core/observables/not_yet_implemented/LbDensityProfile.hpp b/src/core/observables/not_yet_implemented/LbDensityProfile.hpp index 1ab4f540d8..4f6e6ed086 100644 --- a/src/core/observables/not_yet_implemented/LbDensityProfile.hpp +++ b/src/core/observables/not_yet_implemented/LbDensityProfile.hpp @@ -1,85 +1,83 @@ #ifdef LB -int ObservableLbVelocityProfile::actual_calculate(PartCfg & partCfg) { - double* A= last_value; - void* pdata_ = container; +int ObservableLbVelocityProfile::actual_calculate(PartCfg &partCfg) { + double *A = last_value; + void *pdata_ = container; unsigned int n_A = n; unsigned int maxi, maxj, maxk; double xoffset, yoffset, zoffset; double x_incr, y_incr, z_incr; double p[3], v[3]; int linear_index; - profile_data* pdata; - pdata=(profile_data*) container; - + profile_data *pdata; + pdata = (profile_data *)container; #ifdef LB_GPU if (lattice_switch & LATTICE_LB_GPU) - return statistics_observable_lbgpu_velocity_profile((profile_data*) pdata_, A, n_A); + return statistics_observable_lbgpu_velocity_profile((profile_data *)pdata_, + A, n_A); #endif if (lattice_switch & LATTICE_LB) { - for ( int i = 0; ixbins == 1 ) { - maxi = (int) floor(box_l[0]/lbpar.agrid); - normalization_factor/=maxi; - xoffset=0; - x_incr=lbpar.agrid; + if (pdata->xbins == 1) { + maxi = (int)floor(box_l[0] / lbpar.agrid); + normalization_factor /= maxi; + xoffset = 0; + x_incr = lbpar.agrid; } else { maxi = pdata->xbins; - xoffset=pdata->minx; - x_incr=(pdata->maxx-pdata->minx)/(pdata->xbins-1); + xoffset = pdata->minx; + x_incr = (pdata->maxx - pdata->minx) / (pdata->xbins - 1); } - if ( pdata->ybins == 1 ) { - maxj = (int) floor(box_l[1]/lbpar.agrid); - normalization_factor/=maxj; - yoffset=0; - y_incr=lbpar.agrid; + if (pdata->ybins == 1) { + maxj = (int)floor(box_l[1] / lbpar.agrid); + normalization_factor /= maxj; + yoffset = 0; + y_incr = lbpar.agrid; } else { maxj = pdata->ybins; - yoffset=pdata->miny; - y_incr=(pdata->maxy-pdata->miny)/(pdata->ybins-1); + yoffset = pdata->miny; + y_incr = (pdata->maxy - pdata->miny) / (pdata->ybins - 1); } - if ( pdata->zbins == 1 ) { - maxk = (int) floor(box_l[2]/lbpar.agrid); - normalization_factor/=maxk; - zoffset=0; - z_incr=lbpar.agrid; + if (pdata->zbins == 1) { + maxk = (int)floor(box_l[2] / lbpar.agrid); + normalization_factor /= maxk; + zoffset = 0; + z_incr = lbpar.agrid; } else { maxk = pdata->zbins; - zoffset=pdata->minz; - z_incr=(pdata->maxz-pdata->minz)/(pdata->zbins-1); + zoffset = pdata->minz; + z_incr = (pdata->maxz - pdata->minz) / (pdata->zbins - 1); } unsigned int i, j, k; - for ( i = 0; i < maxi; i++ ) { - for ( j = 0; j < maxj; j++ ) { - for ( k = 0; k < maxk; k++ ) { - p[0]=xoffset + i*x_incr; - p[1]=yoffset + j*y_incr; - p[2]=zoffset + k*z_incr; - if (lb_lbfluid_get_interpolated_velocity(p, v)!=0) - return 1; - linear_index = 0; - if (pdata->xbins > 1) - linear_index += i*pdata->ybins*pdata->zbins; - if (pdata->ybins > 1) - linear_index += j*pdata->zbins; - if (pdata->zbins > 1) - linear_index +=k; + for (i = 0; i < maxi; i++) { + for (j = 0; j < maxj; j++) { + for (k = 0; k < maxk; k++) { + p[0] = xoffset + i * x_incr; + p[1] = yoffset + j * y_incr; + p[2] = zoffset + k * z_incr; + if (lb_lbfluid_get_interpolated_velocity(p, v) != 0) + return 1; + linear_index = 0; + if (pdata->xbins > 1) + linear_index += i * pdata->ybins * pdata->zbins; + if (pdata->ybins > 1) + linear_index += j * pdata->zbins; + if (pdata->zbins > 1) + linear_index += k; - A[3*linear_index+0]+=v[0]; - A[3*linear_index+1]+=v[1]; - A[3*linear_index+2]+=v[2]; - } + A[3 * linear_index + 0] += v[0]; + A[3 * linear_index + 1] += v[1]; + A[3 * linear_index + 2] += v[2]; + } } } - - for ( int i = 0; in; i++ ) { + ids = (IntList *)container; + for (int i = 0; i < ids->n; i++) { if (ids->e[i] >= n_part) return 1; - A[3*i + 0] = partCfg[ids->e[i]].f.f[0]/time_step/time_step*2; - A[3*i + 1] = partCfg[ids->e[i]].f.f[1]/time_step/time_step*2; - A[3*i + 2] = partCfg[ids->e[i]].f.f[2]/time_step/time_step*2; + A[3 * i + 0] = partCfg[ids->e[i]].f.f[0] / time_step / time_step * 2; + A[3 * i + 1] = partCfg[ids->e[i]].f.f[1] / time_step / time_step * 2; + A[3 * i + 2] = partCfg[ids->e[i]].f.f[2] / time_step / time_step * 2; } return 0; } diff --git a/src/core/observables/not_yet_implemented/PersistenceLength.hpp b/src/core/observables/not_yet_implemented/PersistenceLength.hpp index b32be06fb9..a2152ae410 100644 --- a/src/core/observables/not_yet_implemented/PersistenceLength.hpp +++ b/src/core/observables/not_yet_implemented/PersistenceLength.hpp @@ -1,33 +1,34 @@ -int ObservablePersistenceLength::actual_calculate(PartCfg & partCfg) { - if (!sortPartCfg()) { - ostringstream errtxt; // = runtimeError(128); - errtxt << "{094 could not sort partCfg}"; - runtimeError(errtxt); - return -1; - } - double* A = last_value; - spatial_polym_data *p_data = (spatial_polym_data *) container; - IntList *ids=p_data->id_list; +int ObservablePersistenceLength::actual_calculate(PartCfg &partCfg) { + if (!sortPartCfg()) { + ostringstream errtxt; // = runtimeError(128); + errtxt << "{094 could not sort partCfg}"; + runtimeError(errtxt); + return -1; + } + double *A = last_value; + spatial_polym_data *p_data = (spatial_polym_data *)container; + IntList *ids = p_data->id_list; - double v1[3]; - double v2[3]; - double abs1, abs2; - int num_parts = ids->n; - int cut_off = p_data->cut_off; - int n_A = n; + double v1[3]; + double v2[3]; + double abs1, abs2; + int num_parts = ids->n; + int cut_off = p_data->cut_off; + int n_A = n; - for (int i = 0; ie[j]].r.p, partCfg[ids->e[j+1]].r.p, v1); - abs1 = normr(v1); - vecsub(partCfg[ids->e[i+j]].r.p, partCfg[ids->e[i+j+1]].r.p, v2); - abs2 = normr(v2); - A[i] += scalar(v1, v2)/(abs1*abs2 * (double) (num_parts - i - 2*cut_off) ); - } - } - return 0; -} + for (int i = 0; i < n_A; i++) { + // i : distance between polymer segments + for (int j = cut_off; j < num_parts - i - cut_off; j++) { + vecsub(partCfg[ids->e[j]].r.p, partCfg[ids->e[j + 1]].r.p, v1); + abs1 = normr(v1); + vecsub(partCfg[ids->e[i + j]].r.p, partCfg[ids->e[i + j + 1]].r.p, v2); + abs2 = normr(v2); + A[i] += scalar(v1, v2) / + (abs1 * abs2 * (double)(num_parts - i - 2 * cut_off)); + } + } + return 0; +} diff --git a/src/core/observables/not_yet_implemented/PolymerKDistribution.hpp b/src/core/observables/not_yet_implemented/PolymerKDistribution.hpp index b287109e10..aba9f744d4 100644 --- a/src/core/observables/not_yet_implemented/PolymerKDistribution.hpp +++ b/src/core/observables/not_yet_implemented/PolymerKDistribution.hpp @@ -1,35 +1,37 @@ -int ObservablePolymerKDistribution::actual_calculate(PartCfg & partCfg) { - if (!sortPartCfg()) { - ostringstream errtxt; - errtxt << "{094 could not sort partCfg}"; - runtimeError(errtxt); - return -1; - } - double* A = last_value; - for (int i = 0; i < n; i++) { - A[i] = 0.0; - } - k_dist_data *data = (k_dist_data *) container; - IntList *ids = data->id_list; - int npoly = data->npoly; - int poly_len = data-> poly_len; - int k = data->k; - double dist_vec[3]; - double dist; - double r_min = data->r_min; - double r_max = data->r_max; - int n_bins = data->n_bins; - int bin_id =0; - double bin_size = (r_max - r_min) / n_bins; - int number_of_pairs =(int) ( floor(poly_len / (k +1 ) ) + ( (poly_len - 1)%(k+1) == 0 ? 1 : 0 ) - 1); - for (int i = 0; i < npoly; i++) - for (int j = 0; j < poly_len - k; j+= k) { - get_mi_vector(dist_vec, partCfg[ids->e[i*poly_len + j]].r.p, partCfg[ids->e[i*poly_len + j + k]].r.p); - dist = normr(dist_vec); - bin_id = (int) floor( (dist - r_min)/bin_size ); - if (bin_id < n_bins && bin_id >= 0) { - A[bin_id] += 1.0/(npoly * number_of_pairs); - } - } - return 0; -} +int ObservablePolymerKDistribution::actual_calculate(PartCfg &partCfg) { + if (!sortPartCfg()) { + ostringstream errtxt; + errtxt << "{094 could not sort partCfg}"; + runtimeError(errtxt); + return -1; + } + double *A = last_value; + for (int i = 0; i < n; i++) { + A[i] = 0.0; + } + k_dist_data *data = (k_dist_data *)container; + IntList *ids = data->id_list; + int npoly = data->npoly; + int poly_len = data->poly_len; + int k = data->k; + double dist_vec[3]; + double dist; + double r_min = data->r_min; + double r_max = data->r_max; + int n_bins = data->n_bins; + int bin_id = 0; + double bin_size = (r_max - r_min) / n_bins; + int number_of_pairs = (int)(floor(poly_len / (k + 1)) + + ((poly_len - 1) % (k + 1) == 0 ? 1 : 0) - 1); + for (int i = 0; i < npoly; i++) + for (int j = 0; j < poly_len - k; j += k) { + get_mi_vector(dist_vec, partCfg[ids->e[i * poly_len + j]].r.p, + partCfg[ids->e[i * poly_len + j + k]].r.p); + dist = normr(dist_vec); + bin_id = (int)floor((dist - r_min) / bin_size); + if (bin_id < n_bins && bin_id >= 0) { + A[bin_id] += 1.0 / (npoly * number_of_pairs); + } + } + return 0; +} diff --git a/src/core/observables/not_yet_implemented/RadialDensityDistribution.hpp b/src/core/observables/not_yet_implemented/RadialDensityDistribution.hpp index dc1709bd0d..6ce2a8082e 100644 --- a/src/core/observables/not_yet_implemented/RadialDensityDistribution.hpp +++ b/src/core/observables/not_yet_implemented/RadialDensityDistribution.hpp @@ -1,51 +1,56 @@ -int ObservableRadialDensityDistribution::actual_calculate(PartCfg & partCfg) { +int ObservableRadialDensityDistribution::actual_calculate(PartCfg &partCfg) { if (!sortPartCfg()) { ostringstream errtxt; // = runtime_error(128); errtxt << "{094 could not sort partCfg} "; - runtimeError(errtxt); + runtimeError(errtxt); return -1; } - radial_density_data *r_data = (radial_density_data *) container; - IntList *ids; - if ( GC_init && Type_array_init ) { - ids = (IntList *) Utils::malloc(sizeof(IntList)); - - //using the grandcanonical scheme, always update the particle id list - ids->e = (int *) Utils::malloc(sizeof(int)*type_array[Index.type[r_data->type]].max_entry); - memmove(ids->e, type_array[Index.type[r_data->type]].id_list, type_array[Index.type[r_data->type]].max_entry*sizeof(int)); - ids->n = type_array[Index.type[r_data->type]].max_entry; - ids->max = type_array[Index.type[r_data->type]].cur_size; - } else { - ids = r_data->id_list; + radial_density_data *r_data = (radial_density_data *)container; + IntList *ids; + if (GC_init && Type_array_init) { + ids = (IntList *)Utils::malloc(sizeof(IntList)); + + // using the grandcanonical scheme, always update the particle id list + ids->e = (int *)Utils::malloc( + sizeof(int) * type_array[Index.type[r_data->type]].max_entry); + memmove(ids->e, type_array[Index.type[r_data->type]].id_list, + type_array[Index.type[r_data->type]].max_entry * sizeof(int)); + ids->n = type_array[Index.type[r_data->type]].max_entry; + ids->max = type_array[Index.type[r_data->type]].cur_size; + } else { + ids = r_data->id_list; } - //r_data->id_list = ids; - //ids = r_data->id_list; + // r_data->id_list = ids; + // ids = r_data->id_list; - double* A = last_value; - int n_A = n; + double *A = last_value; + int n_A = n; double start_point[3]; double end_point[3]; int image_box[3]; - if ( r_data->id_flag ) { - // Using particle_ids to specify the start and endpoints - memmove(start_point, partCfg[r_data->start_point_id].r.p, 3*sizeof(double)); - memmove(image_box, partCfg[r_data->start_point_id].l.i, 3*sizeof(int)); - unfold_position(start_point, image_box); - memmove(end_point, partCfg[r_data->end_point_id].r.p, 3*sizeof(double)); - memmove(image_box, partCfg[r_data->end_point_id].l.i, 3*sizeof(int)); - unfold_position(end_point, image_box); + if (r_data->id_flag) { + // Using particle_ids to specify the start and endpoints + memmove(start_point, partCfg[r_data->start_point_id].r.p, + 3 * sizeof(double)); + memmove(image_box, partCfg[r_data->start_point_id].l.i, 3 * sizeof(int)); + unfold_position(start_point, image_box); + memmove(end_point, partCfg[r_data->end_point_id].r.p, 3 * sizeof(double)); + memmove(image_box, partCfg[r_data->end_point_id].l.i, 3 * sizeof(int)); + unfold_position(end_point, image_box); } else { - memmove(start_point, r_data->start_point, 3*sizeof(double)); - memmove(end_point, r_data->end_point, 3*sizeof(double)); + memmove(start_point, r_data->start_point, 3 * sizeof(double)); + memmove(end_point, r_data->end_point, 3 * sizeof(double)); } - double *bin_volume = (double *) Utils::malloc(sizeof(double)*r_data->rbins); - + double *bin_volume = (double *)Utils::malloc(sizeof(double) * r_data->rbins); + double part_pos[3]; - double AB[3]; // normalized normal vector pointing to start point - double BA[3]; // ... end point - double Apart[3]; // vector difference start_point - part_pos + double AB[3]; // normalized normal vector pointing to start point + double + BA[3]; // ... + // end point + double Apart[3]; // vector difference start_point - part_pos double norm_Apart; double normAB; double dist; @@ -57,93 +62,99 @@ int ObservableRadialDensityDistribution::actual_calculate(PartCfg & partCfg) { int frac = 0; double epsilon = 1e-9; - double rbin_size = (r_data->maxr - r_data->minr)/(r_data->rbins); + double rbin_size = (r_data->maxr - r_data->minr) / (r_data->rbins); int rbin_id; - if ( r_data->id_flag ) { - // in the case of particles use minimal image convention for axis definition - get_mi_vector(AB, start_point, end_point); - get_mi_vector(BA, end_point, start_point); - if ( normr(AB) < epsilon ) { - //start and end point are periodic images of one another - periodic_points = 1; - } - end_point[0] = start_point[0] - AB[0]; - end_point[1] = start_point[1] - AB[1]; - end_point[2] = start_point[2] - AB[2]; + if (r_data->id_flag) { + // in the case of particles use minimal image convention for axis definition + get_mi_vector(AB, start_point, end_point); + get_mi_vector(BA, end_point, start_point); + if (normr(AB) < epsilon) { + // start and end point are periodic images of one another + periodic_points = 1; + } + end_point[0] = start_point[0] - AB[0]; + end_point[1] = start_point[1] - AB[1]; + end_point[2] = start_point[2] - AB[2]; } else { - // otherwise use the given absolute positions but check whether those points are too close - get_mi_vector(AB, start_point, end_point); - if ( normr(AB) < epsilon ) { - //start and end point are periodic images of one another - periodic_points = 1; - } - vecsub(start_point, end_point, AB); - vecsub(end_point, start_point, BA); + // otherwise use the given absolute positions but check whether those points + // are too close + get_mi_vector(AB, start_point, end_point); + if (normr(AB) < epsilon) { + // start and end point are periodic images of one another + periodic_points = 1; + } + vecsub(start_point, end_point, AB); + vecsub(end_point, start_point, BA); } - //printf("id: %d, lenAB: %1.3e, lenBA: %1.3e, %f %f %f, %f %f %f\n", r_data->id_flag, normr(AB), normr(BA), start_point[0], start_point[1], start_point[2], end_point[0], end_point[1], end_point[2]); - normAB = normr(AB); - for (int i=0; irbins; i++) { - bin_volume[i] = normAB*( pow(r_data->minr + (i+1)*rbin_size, 2) - pow(r_data->minr + i*rbin_size, 2) ) * PI; + // printf("id: %d, lenAB: %1.3e, lenBA: %1.3e, %f %f %f, %f %f %f\n", + // r_data->id_flag, normr(AB), normr(BA), start_point[0], start_point[1], + // start_point[2], end_point[0], end_point[1], end_point[2]); + normAB = normr(AB); + for (int i = 0; i < r_data->rbins; i++) { + bin_volume[i] = normAB * (pow(r_data->minr + (i + 1) * rbin_size, 2) - + pow(r_data->minr + i * rbin_size, 2)) * + PI; } unit_vector(AB, AB); unit_vector(BA, BA); - for (int i=0; in; i++){ - part_pos[0]=partCfg[ids->e[i]].r.p[0]; - part_pos[1]=partCfg[ids->e[i]].r.p[1]; - part_pos[2]=partCfg[ids->e[i]].r.p[2]; - // that might seem weird, but this ensures that the used particle position is the - // closest image to one of the two points that define the axis - get_mi_vector(tmp, part_pos, start_point); - get_mi_vector(tmp2, part_pos, end_point); - - if ( periodic_points ) { - // the axis spans the whole box, so any particle is in - // scope - dist = -1; - } else if ( normr(tmp) < normr(tmp2) ) { - part_pos[0] = start_point[0] + tmp[0]; - part_pos[1] = start_point[1] + tmp[1]; - part_pos[2] = start_point[2] + tmp[2]; - dist = scalar(AB, tmp); - } else { - part_pos[0] = end_point[0] + tmp2[0]; - part_pos[1] = end_point[1] + tmp2[1]; - part_pos[2] = end_point[2] + tmp2[2]; - dist = scalar(BA, tmp2); - } - - if (dist > 0 ) { - - continue; - } - - // particle in scope - // now calculate the distance from the given axis using simple geometry - vecsub(start_point, part_pos, Apart); - - norm_Apart = normr(Apart); - angle = acos(scalar(Apart, AB)/norm_Apart); - r_dist= sin(angle)*norm_Apart; - - rbin_id = (int) floor( (r_dist - r_data->minr)/rbin_size ); - if ( rbin_id >= r_data->rbins || rbin_id < 0 ) - continue; - - A[rbin_id]+=1.0/bin_volume[rbin_id]; - frac++; + for (int i = 0; i < n_A; i++) + A[i] = 0.0; + + for (int i = 0; i < ids->n; i++) { + part_pos[0] = partCfg[ids->e[i]].r.p[0]; + part_pos[1] = partCfg[ids->e[i]].r.p[1]; + part_pos[2] = partCfg[ids->e[i]].r.p[2]; + // that might seem weird, but this ensures that the used particle position + // is the + // closest image to one of the two points that define the axis + get_mi_vector(tmp, part_pos, start_point); + get_mi_vector(tmp2, part_pos, end_point); + + if (periodic_points) { + // the axis spans the whole box, so any particle is in + // scope + dist = -1; + } else if (normr(tmp) < normr(tmp2)) { + part_pos[0] = start_point[0] + tmp[0]; + part_pos[1] = start_point[1] + tmp[1]; + part_pos[2] = start_point[2] + tmp[2]; + dist = scalar(AB, tmp); + } else { + part_pos[0] = end_point[0] + tmp2[0]; + part_pos[1] = end_point[1] + tmp2[1]; + part_pos[2] = end_point[2] + tmp2[2]; + dist = scalar(BA, tmp2); + } + + if (dist > 0) { + + continue; + } + + // particle in scope + // now calculate the distance from the given axis using simple geometry + vecsub(start_point, part_pos, Apart); + + norm_Apart = normr(Apart); + angle = acos(scalar(Apart, AB) / norm_Apart); + r_dist = sin(angle) * norm_Apart; + + rbin_id = (int)floor((r_dist - r_data->minr) / rbin_size); + if (rbin_id >= r_data->rbins || rbin_id < 0) + continue; + + A[rbin_id] += 1.0 / bin_volume[rbin_id]; + frac++; } -// printf("fraction of parts: %d %d\n", frac, ids->n); + // printf("fraction of parts: %d %d\n", frac, ids->n); free(bin_volume); - if ( GC_init && Type_array_init ) { - free(ids->e); - free(ids); - } + if (GC_init && Type_array_init) { + free(ids->e); + free(ids); + } return 0; } diff --git a/src/core/observables/not_yet_implemented/RadialDensityProfile.hpp b/src/core/observables/not_yet_implemented/RadialDensityProfile.hpp index 70cfc7744c..41c954ecc6 100644 --- a/src/core/observables/not_yet_implemented/RadialDensityProfile.hpp +++ b/src/core/observables/not_yet_implemented/RadialDensityProfile.hpp @@ -1,43 +1,53 @@ -int ObservableRadialDensityProfile::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableRadialDensityProfile::actual_calculate(PartCfg &partCfg) { + double *A = last_value; int binr, binphi, binz; double ppos[3]; double r, phi, z; int img[3]; double bin_volume; - IntList* ids; - + IntList *ids; + if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - radial_profile_data* pdata; - pdata=(radial_profile_data*) container; - ids=pdata->id_list; - double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; - double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; - double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; - - for (int i = 0; i< n; i++ ) { - A[i]=0; + radial_profile_data *pdata; + pdata = (radial_profile_data *)container; + ids = pdata->id_list; + double rbinsize = (pdata->maxr - pdata->minr) / pdata->rbins; + double phibinsize = (pdata->maxphi - pdata->minphi) / pdata->phibins; + double zbinsize = (pdata->maxz - pdata->minz) / pdata->zbins; + + for (int i = 0; i < n; i++) { + A[i] = 0; } - for (int i = 0; in; i++ ) { + for (int i = 0; i < ids->n; i++) { if (ids->e[i] >= n_part) return 1; -/* We use folded coordinates here */ - memmove(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); - memmove(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); + /* We use folded coordinates here */ + memmove(ppos, partCfg[ids->e[i]].r.p, 3 * sizeof(double)); + memmove(img, partCfg[ids->e[i]].l.i, 3 * sizeof(int)); fold_position(ppos, img); - transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); - //printf("%f %f %f %f %f %f\n", ppos[0], ppos[1], ppos[2], r*cos(phi)+pdata->center[0], r*sin(phi)+pdata->center[1], z+pdata->center[2]); - binr =(int)floor((r-pdata->minr)/rbinsize); - binphi=(int)floor((phi-pdata->minphi)/phibinsize); - binz =(int)floor((z-pdata->minz)/zbinsize); + transform_to_cylinder_coordinates(ppos[0] - pdata->center[0], + ppos[1] - pdata->center[1], + ppos[2] - pdata->center[2], &r, &phi, &z); + // printf("%f %f %f %f %f %f\n", ppos[0], ppos[1], ppos[2], + // r*cos(phi)+pdata->center[0], r*sin(phi)+pdata->center[1], + // z+pdata->center[2]); + binr = (int)floor((r - pdata->minr) / rbinsize); + binphi = (int)floor((phi - pdata->minphi) / phibinsize); + binz = (int)floor((z - pdata->minz) / zbinsize); - if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { - bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; - A[binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz] += 1./bin_volume; - } + if (binr >= 0 && binr < pdata->rbins && binphi >= 0 && + binphi < pdata->phibins && binz >= 0 && binz < pdata->zbins) { + bin_volume = PI * ((pdata->minr + (binr + 1) * rbinsize) * + (pdata->minr + (binr + 1) * rbinsize) - + (pdata->minr + (binr)*rbinsize) * + (pdata->minr + (binr)*rbinsize)) * + zbinsize * phibinsize / 2 / PI; + A[binr * pdata->phibins * pdata->zbins + binphi * pdata->zbins + binz] += + 1. / bin_volume; + } } return 0; } diff --git a/src/core/observables/not_yet_implemented/RadialFluxDensityProfile.hpp b/src/core/observables/not_yet_implemented/RadialFluxDensityProfile.hpp index 40ba3b43a1..1396986158 100644 --- a/src/core/observables/not_yet_implemented/RadialFluxDensityProfile.hpp +++ b/src/core/observables/not_yet_implemented/RadialFluxDensityProfile.hpp @@ -1,85 +1,106 @@ -int ObservableRadialFluxDensityProfile::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableRadialFluxDensityProfile::actual_calculate(PartCfg &partCfg) { + double *A = last_value; int binr, binphi, binz; double ppos[3]; double unfolded_ppos[3]; double r, phi, z; int img[3]; double bin_volume; - IntList* ids; + IntList *ids; if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - radial_profile_data* pdata; - pdata=(radial_profile_data*) container; - ids=pdata->id_list; - double rbinsize=(pdata->maxr - pdata->minr)/pdata->rbins; - double phibinsize=(pdata->maxphi - pdata->minphi)/pdata->phibins; - double zbinsize=(pdata->maxz - pdata->minz)/pdata->zbins; + radial_profile_data *pdata; + pdata = (radial_profile_data *)container; + ids = pdata->id_list; + double rbinsize = (pdata->maxr - pdata->minr) / pdata->rbins; + double phibinsize = (pdata->maxphi - pdata->minphi) / pdata->phibins; + double zbinsize = (pdata->maxz - pdata->minz) / pdata->zbins; double v[3]; double v_r, v_phi, v_z; - if (last_update==sim_time) { + if (last_update == sim_time) { return ES_ERROR; } - - for (int i = 0; i< n; i++ ) { - A[i]=0; + + for (int i = 0; i < n; i++) { + A[i] = 0; } - double* old_positions=(double*) pdata->container; + double *old_positions = (double *)pdata->container; if (old_positions[0] == CONST_UNITITIALIZED) { - for (int i = 0; in; i++ ) { - memmove(unfolded_ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); - memmove(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); + for (int i = 0; i < ids->n; i++) { + memmove(unfolded_ppos, partCfg[ids->e[i]].r.p, 3 * sizeof(double)); + memmove(img, partCfg[ids->e[i]].l.i, 3 * sizeof(int)); unfold_position(unfolded_ppos, img); - old_positions[3*i+0]=unfolded_ppos[0]; - old_positions[3*i+1]=unfolded_ppos[1]; - old_positions[3*i+2]=unfolded_ppos[2]; + old_positions[3 * i + 0] = unfolded_ppos[0]; + old_positions[3 * i + 1] = unfolded_ppos[1]; + old_positions[3 * i + 2] = unfolded_ppos[2]; } return 0; } - for (int i = 0; in; i++ ) { + for (int i = 0; i < ids->n; i++) { if (ids->e[i] >= n_part) return 1; -/* We use folded coordinates here */ - memmove(unfolded_ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); - memmove(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); + /* We use folded coordinates here */ + memmove(unfolded_ppos, partCfg[ids->e[i]].r.p, 3 * sizeof(double)); + memmove(img, partCfg[ids->e[i]].l.i, 3 * sizeof(int)); unfold_position(unfolded_ppos, img); - v[0]=(unfolded_ppos[0] - old_positions[3*i+0]); - v[1]=(unfolded_ppos[1] - old_positions[3*i+1]); - v[2]=(unfolded_ppos[2] - old_positions[3*i+2]); - memmove(ppos, partCfg[ids->e[i]].r.p, 3*sizeof(double)); - memmove(img, partCfg[ids->e[i]].l.i, 3*sizeof(int)); + v[0] = (unfolded_ppos[0] - old_positions[3 * i + 0]); + v[1] = (unfolded_ppos[1] - old_positions[3 * i + 1]); + v[2] = (unfolded_ppos[2] - old_positions[3 * i + 2]); + memmove(ppos, partCfg[ids->e[i]].r.p, 3 * sizeof(double)); + memmove(img, partCfg[ids->e[i]].l.i, 3 * sizeof(int)); fold_position(ppos, img); - // The position of the particle is by definition the middle of old and new position - ppos[0]+=0.5*v[0]; ppos[1]+=0.5*v[1]; ppos[2]+=0.5*v[2]; + // The position of the particle is by definition the middle of old and new + // position + ppos[0] += 0.5 * v[0]; + ppos[1] += 0.5 * v[1]; + ppos[2] += 0.5 * v[2]; fold_position(ppos, img); - v[0]/=(sim_time - last_update); - v[1]/=(sim_time - last_update); - v[2]/=(sim_time - last_update); - if (i==0) { -// printf("(%3.4f) %f %f %f\n", sim_time-last_update, v[2], partCfg[ids->e[i]].m.v[2]/time_step,v[2]* partCfg[ids->e[i]].m.v[2]/time_step/time_step); -// printf("(%3.3f) %f %f", sim_time, old_positions[3*i+2], unfolded_ppos[2]); + v[0] /= (sim_time - last_update); + v[1] /= (sim_time - last_update); + v[2] /= (sim_time - last_update); + if (i == 0) { + // printf("(%3.4f) %f %f %f\n", sim_time-last_update, v[2], + // partCfg[ids->e[i]].m.v[2]/time_step,v[2]* + // partCfg[ids->e[i]].m.v[2]/time_step/time_step); + // printf("(%3.3f) %f %f", sim_time, old_positions[3*i+2], + // unfolded_ppos[2]); } - old_positions[3*i+0]=unfolded_ppos[0]; - old_positions[3*i+1]=unfolded_ppos[1]; - old_positions[3*i+2]=unfolded_ppos[2]; - transform_to_cylinder_coordinates(ppos[0]-pdata->center[0], ppos[1]-pdata->center[1], ppos[2]-pdata->center[2], &r, &phi, &z); - binr =(int)floor((r-pdata->minr)/rbinsize); - binphi=(int)floor((phi-pdata->minphi)/phibinsize); - binz =(int)floor((z-pdata->minz)/zbinsize); + old_positions[3 * i + 0] = unfolded_ppos[0]; + old_positions[3 * i + 1] = unfolded_ppos[1]; + old_positions[3 * i + 2] = unfolded_ppos[2]; + transform_to_cylinder_coordinates(ppos[0] - pdata->center[0], + ppos[1] - pdata->center[1], + ppos[2] - pdata->center[2], &r, &phi, &z); + binr = (int)floor((r - pdata->minr) / rbinsize); + binphi = (int)floor((phi - pdata->minphi) / phibinsize); + binz = (int)floor((z - pdata->minz) / zbinsize); - if (binr>=0 && binr < pdata->rbins && binphi>=0 && binphi < pdata->phibins && binz>=0 && binz < pdata->zbins) { - bin_volume=PI*((pdata->minr+(binr+1)*rbinsize)*(pdata->minr+(binr+1)*rbinsize) - (pdata->minr+(binr)*rbinsize)*(pdata->minr+(binr)*rbinsize)) *zbinsize * phibinsize/2/PI; - v_r = 1/r*((ppos[0]-pdata->center[0])*v[0] + (ppos[1]-pdata->center[1])*v[1]); - v_phi = 1/r/r*((ppos[0]-pdata->center[0])*v[1]-(ppos[1]-pdata->center[1])*v[0]); + if (binr >= 0 && binr < pdata->rbins && binphi >= 0 && + binphi < pdata->phibins && binz >= 0 && binz < pdata->zbins) { + bin_volume = PI * ((pdata->minr + (binr + 1) * rbinsize) * + (pdata->minr + (binr + 1) * rbinsize) - + (pdata->minr + (binr)*rbinsize) * + (pdata->minr + (binr)*rbinsize)) * + zbinsize * phibinsize / 2 / PI; + v_r = 1 / r * ((ppos[0] - pdata->center[0]) * v[0] + + (ppos[1] - pdata->center[1]) * v[1]); + v_phi = 1 / r / r * ((ppos[0] - pdata->center[0]) * v[1] - + (ppos[1] - pdata->center[1]) * v[0]); v_z = v[2]; - A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 0] += v_r/bin_volume; - A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 1] += v_phi/bin_volume; - A[3*(binr*pdata->phibins*pdata->zbins + binphi*pdata->zbins + binz) + 2] += v_z/bin_volume; - } + A[3 * (binr * pdata->phibins * pdata->zbins + binphi * pdata->zbins + + binz) + + 0] += v_r / bin_volume; + A[3 * (binr * pdata->phibins * pdata->zbins + binphi * pdata->zbins + + binz) + + 1] += v_phi / bin_volume; + A[3 * (binr * pdata->phibins * pdata->zbins + binphi * pdata->zbins + + binz) + + 2] += v_z / bin_volume; + } } return 0; } diff --git a/src/core/observables/not_yet_implemented/Rdf.hpp b/src/core/observables/not_yet_implemented/Rdf.hpp index 9adf8c2a4f..ec41f9c097 100644 --- a/src/core/observables/not_yet_implemented/Rdf.hpp +++ b/src/core/observables/not_yet_implemented/Rdf.hpp @@ -1,12 +1,11 @@ -int ObservableRdf::actual_calculate(PartCfg & partCfg) { +int ObservableRdf::actual_calculate(PartCfg &partCfg) { if (!sortPartCfg()) { return 1; } - double * last = last_value; - rdf_profile_data * rdf_data = (rdf_profile_data *) container; - calc_rdf(rdf_data->p1_types, rdf_data->n_p1, - rdf_data->p2_types, rdf_data->n_p2, - rdf_data->r_min, rdf_data->r_max, - rdf_data->r_bins, last); + double *last = last_value; + rdf_profile_data *rdf_data = (rdf_profile_data *)container; + calc_rdf(rdf_data->p1_types, rdf_data->n_p1, rdf_data->p2_types, + rdf_data->n_p2, rdf_data->r_min, rdf_data->r_max, rdf_data->r_bins, + last); return 0; } diff --git a/src/core/observables/not_yet_implemented/SpatialPolymerProperties.hpp b/src/core/observables/not_yet_implemented/SpatialPolymerProperties.hpp index 6934edb1b1..4ddaba4cb9 100644 --- a/src/core/observables/not_yet_implemented/SpatialPolymerProperties.hpp +++ b/src/core/observables/not_yet_implemented/SpatialPolymerProperties.hpp @@ -1,21 +1,21 @@ -int ObbservableSpatialPolymerProperties::actual_calculate(PartCfg & partCfg) { - if (!sortPartCfg()) { - ostringstream errtxt ; //= runtime_error(128); - errtxt << "{094 could not sort partCfg}"; - runtimeError(errtxt); - return -1; - } - double* A = last_value; - int poly_len = n; - for (int i = 0; iid_list; - for (int i = 0; in; i++){ - A[i%poly_len] += partCfg[ids->e[i]].p.q/( (double) p_data->npoly); - } + spatial_polym_data *p_data = (spatial_polym_data *)container; + IntList *ids = p_data->id_list; + for (int i = 0; i < ids->n; i++) { + A[i % poly_len] += partCfg[ids->e[i]].p.q / ((double)p_data->npoly); + } #endif - return 0; + return 0; } diff --git a/src/core/observables/not_yet_implemented/StructureFactor.hpp b/src/core/observables/not_yet_implemented/StructureFactor.hpp index 757ee03112..e1a5ca8bb2 100644 --- a/src/core/observables/not_yet_implemented/StructureFactor.hpp +++ b/src/core/observables/not_yet_implemented/StructureFactor.hpp @@ -1,57 +1,60 @@ -int ObservableStructureFactor::actual_calculate(PartCfg & partCfg) { - double* A = last_value; +int ObservableStructureFactor::actual_calculate(PartCfg &partCfg) { + double *A = last_value; // FIXME Currently scattering length is hardcoded as 1.0 int l; int order, order2, n; - double twoPI_L, C_sum, S_sum, qr; + double twoPI_L, C_sum, S_sum, qr; // DoubleList *scattering_length; - observable_sf_params * params; - params = (observable_sf_params*) container; + observable_sf_params *params; + params = (observable_sf_params *)container; // scattering_length = params->scattering_length; - const double scattering_length=1.0; + const double scattering_length = 1.0; order = params->order; - order2=order*order; - twoPI_L = 2*PI/box_l[0]; - + order2 = order * order; + twoPI_L = 2 * PI / box_l[0]; + if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - - l=0; - float partCache[n_part*3]; - for(int p=0; p=1)) { - C_sum = S_sum = 0.0; - //printf("l: %d, n: %d %d %d\n",l,i,j,k); fflush(stdout); - for(int p=0; p= 1)) { + C_sum = S_sum = 0.0; + // printf("l: %d, n: %d %d %d\n",l,i,j,k); fflush(stdout); + for (int p = 0; p < n_part; p++) { + // qr = twoPI_L * ( i*partCfg[p].r.p[0] + j*partCfg[p].r.p[1] + + // k*partCfg[p].r.p[2] ); + qr = + twoPI_L * (i * partCache[3 * p + 0] + j * partCache[3 * p + 1] + + k * partCache[3 * p + 2]); + C_sum += scattering_length * cos(qr); + S_sum -= scattering_length * sin(qr); + } + A[l] = C_sum; + A[l + 1] = S_sum; + l = l + 2; + } } } } l = 0; - for(int k=0;korder * params->k_density; - const double scattering_length=1.0; - const double twoPI_L = 2*PI/box_l[0]; - + const double scattering_length = 1.0; + const double twoPI_L = 2 * PI / box_l[0]; + if (!sortPartCfg()) { - runtimeErrorMsg() <<"could not sort partCfg"; + runtimeErrorMsg() << "could not sort partCfg"; return -1; } - - for(int p=0; pk_density; - int l=0; - for(int k=0; k. + along with this program. If not, see . */ /** \file p3m-common.cpp P3M main file. */ @@ -62,51 +62,58 @@ void p3m_common_parameter_pre_init(p3m_parameter_struct *params) { } /** Debug function printing p3m structures */ -void p3m_p3m_print_local_mesh(p3m_local_mesh l) -{ - fprintf(stderr,"%d: p3m_local_mesh: dim=(%d,%d,%d), size=%d\n",this_node, - l.dim[0],l.dim[1],l.dim[2],l.size); - fprintf(stderr,"%d: ld_ind=(%d,%d,%d), ld_pos=(%f,%f,%f)\n",this_node, - l.ld_ind[0],l.ld_ind[1],l.ld_ind[2], - l.ld_pos[0],l.ld_pos[1],l.ld_pos[2]); - fprintf(stderr,"%d: inner=(%d,%d,%d) [(%d,%d,%d)-(%d,%d,%d)]\n",this_node, - l.inner[0],l.inner[1],l.inner[2], - l.in_ld[0],l.in_ld[1],l.in_ld[2], - l.in_ur[0],l.in_ur[1],l.in_ur[2]); - fprintf(stderr,"%d: margin = (%d,%d, %d,%d, %d,%d)\n",this_node, - l.margin[0],l.margin[1],l.margin[2],l.margin[3],l.margin[4],l.margin[5]); - fprintf(stderr,"%d: r_margin=(%d,%d, %d,%d, %d,%d)\n",this_node, - l.r_margin[0],l.r_margin[1],l.r_margin[2],l.r_margin[3],l.r_margin[4],l.r_margin[5]); +void p3m_p3m_print_local_mesh(p3m_local_mesh l) { + fprintf(stderr, "%d: p3m_local_mesh: dim=(%d,%d,%d), size=%d\n", this_node, + l.dim[0], l.dim[1], l.dim[2], l.size); + fprintf(stderr, "%d: ld_ind=(%d,%d,%d), ld_pos=(%f,%f,%f)\n", this_node, + l.ld_ind[0], l.ld_ind[1], l.ld_ind[2], l.ld_pos[0], l.ld_pos[1], + l.ld_pos[2]); + fprintf(stderr, "%d: inner=(%d,%d,%d) [(%d,%d,%d)-(%d,%d,%d)]\n", + this_node, l.inner[0], l.inner[1], l.inner[2], l.in_ld[0], l.in_ld[1], + l.in_ld[2], l.in_ur[0], l.in_ur[1], l.in_ur[2]); + fprintf(stderr, "%d: margin = (%d,%d, %d,%d, %d,%d)\n", this_node, + l.margin[0], l.margin[1], l.margin[2], l.margin[3], l.margin[4], + l.margin[5]); + fprintf(stderr, "%d: r_margin=(%d,%d, %d,%d, %d,%d)\n", this_node, + l.r_margin[0], l.r_margin[1], l.r_margin[2], l.r_margin[3], + l.r_margin[4], l.r_margin[5]); } /** Debug function printing p3m structures */ -void p3m_p3m_print_send_mesh(p3m_send_mesh sm) -{ +void p3m_p3m_print_send_mesh(p3m_send_mesh sm) { int i; - fprintf(stderr,"%d: p3m_send_mesh: max=%d\n",this_node,sm.max); - for(i=0;i<6;i++) { - fprintf(stderr,"%d: dir=%d: s_dim (%d,%d,%d) s_ld (%d,%d,%d) s_ur (%d,%d,%d) s_size=%d\n",this_node,i,sm.s_dim[i][0],sm.s_dim[i][1],sm.s_dim[i][2],sm.s_ld[i][0],sm.s_ld[i][1],sm.s_ld[i][2],sm.s_ur[i][0],sm.s_ur[i][1],sm.s_ur[i][2],sm.s_size[i]); - fprintf(stderr,"%d: r_dim (%d,%d,%d) r_ld (%d,%d,%d) r_ur (%d,%d,%d) r_size=%d\n",this_node,sm.r_dim[i][0],sm.r_dim[i][1],sm.r_dim[i][2],sm.r_ld[i][0],sm.r_ld[i][1],sm.r_ld[i][2],sm.r_ur[i][0],sm.r_ur[i][1],sm.r_ur[i][2],sm.r_size[i]); + fprintf(stderr, "%d: p3m_send_mesh: max=%d\n", this_node, sm.max); + for (i = 0; i < 6; i++) { + fprintf(stderr, "%d: dir=%d: s_dim (%d,%d,%d) s_ld (%d,%d,%d) s_ur " + "(%d,%d,%d) s_size=%d\n", + this_node, i, sm.s_dim[i][0], sm.s_dim[i][1], sm.s_dim[i][2], + sm.s_ld[i][0], sm.s_ld[i][1], sm.s_ld[i][2], sm.s_ur[i][0], + sm.s_ur[i][1], sm.s_ur[i][2], sm.s_size[i]); + fprintf(stderr, "%d: r_dim (%d,%d,%d) r_ld (%d,%d,%d) r_ur " + "(%d,%d,%d) r_size=%d\n", + this_node, sm.r_dim[i][0], sm.r_dim[i][1], sm.r_dim[i][2], + sm.r_ld[i][0], sm.r_ld[i][1], sm.r_ld[i][2], sm.r_ur[i][0], + sm.r_ur[i][1], sm.r_ur[i][2], sm.r_size[i]); } } -void p3m_add_block(double *in, double *out, int start[3], int size[3], int dim[3]) -{ +void p3m_add_block(double *in, double *out, int start[3], int size[3], + int dim[3]) { /* fast,mid and slow changing indices */ - int f,m,s; + int f, m, s; /* linear index of in grid, linear index of out grid */ - int li_in=0,li_out=0; + int li_in = 0, li_out = 0; /* offsets for indizes in output grid */ - int m_out_offset,s_out_offset; + int m_out_offset, s_out_offset; - li_out = start[2] + ( dim[2]*( start[1] + (dim[1]*start[0]) ) ); - m_out_offset = dim[2] - size[2]; - s_out_offset = (dim[2] * (dim[1] - size[1])); + li_out = start[2] + (dim[2] * (start[1] + (dim[1] * start[0]))); + m_out_offset = dim[2] - size[2]; + s_out_offset = (dim[2] * (dim[1] - size[1])); - for(s=0 ;s. + along with this program. If not, see . */ -#ifndef _P3M_COMMON_H +#ifndef _P3M_COMMON_H #define _P3M_COMMON_H /** \file p3m-common.hpp common functions for dipolar and charge p3m. * @@ -27,12 +27,12 @@ * Hockney/Eastwood and Deserno/Holm. The file p3m contains only the * Particle-Mesh part. * - * Further reading: + * Further reading: *
    *
  • P.P. Ewald, * Die Berechnung optischer und elektrostatischer Gitterpotentiale, * Ann. Phys. (64) 253-287, 1921 - *
  • R. W. Hockney and J. W. Eastwood, + *
  • R. W. Hockney and J. W. Eastwood, * Computer Simulation Using Particles, * IOP, London, 1988 *
  • M. Deserno and C. Holm, @@ -45,7 +45,8 @@ *
  • M. Deserno, * Counterion condensation for rigid linear polyelectrolytes, * PhdThesis, Universit{\"a}t Mainz, 2000 - *
  • J.J. Cerda, P3M for dipolar interactions. J. Chem. Phys, 129, xxx ,(2008). + *
  • J.J. Cerda, P3M for dipolar interactions. J. Chem. Phys, 129, xxx + * ,(2008). *
* */ @@ -58,7 +59,7 @@ #define P3M_EPSILON_METALLIC 0.0 /** increment size of charge assignment fields. */ -#define CA_INCREMENT 32 +#define CA_INCREMENT 32 /** precision limit for the r_cut zero */ #define P3M_RCUT_PREC 1e-3 /** granularity of the time measurement */ @@ -78,7 +79,7 @@ typedef struct { int dim[3]; /** number of local mesh points. */ int size; - /** index of lower left corner of the + /** index of lower left corner of the local mesh in the global mesh. */ int ld_ind[3]; /** position of the first local mesh point. */ @@ -125,19 +126,21 @@ typedef struct { typedef struct { /** Tuning or production? */ bool tuning; - /** Ewald splitting parameter (00), rescaled to r_cut_iL = r_cut * box_l_i. */ + /** Cutoff radius for real space electrostatics (>0), rescaled to r_cut_iL = + * r_cut * box_l_i. */ double r_cut_iL; /** number of mesh points per coordinate direction (>0). */ - int mesh[3]; + int mesh[3]; /** offset of the first mesh point (lower left corner) from the coordinate origin ([0,1[). */ double mesh_off[3]; /** charge assignment order ([0,7]). */ - int cao; + int cao; /** number of interpolation points for charge assignment function */ - int inter; + int inter; /** Accuracy of the actual parameter set. */ double accuracy; @@ -155,9 +158,11 @@ typedef struct { double r_cut; /** full size of the interpolated assignment function */ int inter2; - /** number of points unto which a single charge is interpolated, i.e. p3m.cao^3 */ + /** number of points unto which a single charge is interpolated, i.e. + * p3m.cao^3 */ int cao3; - /** additional points around the charge assignment mesh, for method like dielectric ELC + /** additional points around the charge assignment mesh, for method like + dielectric ELC creating virtual charges. */ double additional_mesh[3]; } p3m_parameter_struct; @@ -165,18 +170,18 @@ typedef struct { /** initialize the parameter struct */ void p3m_common_parameter_pre_init(p3m_parameter_struct *params); -/** print local mesh content. +/** print local mesh content. \param l local mesh structure. */ void p3m_p3m_print_local_mesh(p3m_local_mesh l); -/** print send mesh content. +/** print send mesh content. * \param sm send mesh structure. */ void p3m_p3m_print_send_mesh(p3m_send_mesh sm); /** Add values of a 3d-grid input block (size[3]) to values of 3d-grid - * ouput array with dimension dim[3] at start position start[3]. + * ouput array with dimension dim[3] at start position start[3]. * * \param in Pointer to first element of input block data. * \param out Pointer to first element of output grid. @@ -184,9 +189,10 @@ void p3m_p3m_print_send_mesh(p3m_send_mesh sm); * \param size Dimensions of the block * \param dim Dimensions of the output grid. */ -void p3m_add_block(double *in, double *out, int start[3], int size[3], int dim[3]); +void p3m_add_block(double *in, double *out, int start[3], int size[3], + int dim[3]); -/** One of the aliasing sums used by \ref p3m_k_space_error. +/** One of the aliasing sums used by \ref p3m_k_space_error. (fortunately the one which is most important (because it converges most slowly, since it is not damped exponentially)) can be calculated analytically. The result (which depends on the order of @@ -197,7 +203,7 @@ double p3m_analytic_cotangent_sum(int n, double mesh_i, int cao); /** Computes the assignment function of for the \a i'th degree at value \a x. */ -double p3m_caf(int i, double x,int cao_value); +double p3m_caf(int i, double x, int cao_value); #endif /* P3M || DP3M */ diff --git a/src/core/p3m-dipolar.cpp b/src/core/p3m-dipolar.cpp index 591be45a30..93b57822e8 100644 --- a/src/core/p3m-dipolar.cpp +++ b/src/core/p3m-dipolar.cpp @@ -460,10 +460,9 @@ double dp3m_average_dipolar_self_energy(double box_l, int mesh) { node_phi += 0.0; else { U2 = dp3m_perform_aliasing_sums_dipolar_self_energy(n); - node_phi += - dp3m.g_energy[ind] * U2 * - (Utils::sqr(dp3m.d_op[n[0]]) + Utils::sqr(dp3m.d_op[n[1]]) + - Utils::sqr(dp3m.d_op[n[2]])); + node_phi += dp3m.g_energy[ind] * U2 * (Utils::sqr(dp3m.d_op[n[0]]) + + Utils::sqr(dp3m.d_op[n[1]]) + + Utils::sqr(dp3m.d_op[n[2]])); } } } @@ -612,9 +611,8 @@ void dp3m_interpolate_dipole_assignment_function() { if (dp3m.params.inter == 0) return; - P3M_TRACE(fprintf(stderr, - "dipolar %d - interpolating (%d) the order-%d " - "charge assignment function\n", + P3M_TRACE(fprintf(stderr, "dipolar %d - interpolating (%d) the order-%d " + "charge assignment function\n", this_node, dp3m.params.inter, dp3m.params.cao)); dp3m.params.inter2 = 2 * dp3m.params.inter + 1; @@ -1554,13 +1552,13 @@ double dp3m_perform_aliasing_sums_energy(int n[3], double nominator[1]) { return denominator; } - /*****************************************************************************/ +/*****************************************************************************/ - /************************************************ - * Functions for dipoloar P3M Parameter tuning - * This tuning is based on the P3M tuning of the charges - which in turn is based on the P3M_tune by M. Deserno - ************************************************/ +/************************************************ + * Functions for dipoloar P3M Parameter tuning + * This tuning is based on the P3M tuning of the charges + which in turn is based on the P3M_tune by M. Deserno + ************************************************/ #define P3M_TUNE_MAX_CUTS 50 /** Tune dipolar P3M parameters to desired accuracy. @@ -1924,9 +1922,8 @@ static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, else if (tmp_time > best_time + P3M_TIME_GRAN) break; } - P3M_TRACE(fprintf(stderr, - "dp3m_m_time: " - "Dmesh=%d final Dcao=%d Dr_cut=%f time=%f\n", + P3M_TRACE(fprintf(stderr, "dp3m_m_time: " + "Dmesh=%d final Dcao=%d Dr_cut=%f time=%f\n", mesh, *_cao, *_r_cut_iL, best_time)); return best_time; } @@ -1969,9 +1966,8 @@ int dp3m_adaptive_tune(char **logger) { mpi_bcast_event(P3M_COUNT_DIPOLES); /* Print Status */ - sprintf(b, - "Dipolar P3M tune parameters: Accuracy goal = %.5e prefactor " - "= %.5e\n", + sprintf(b, "Dipolar P3M tune parameters: Accuracy goal = %.5e prefactor " + "= %.5e\n", dp3m.params.accuracy, coulomb.Dprefactor); *logger = strcat_alloc(*logger, b); sprintf(b, "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", @@ -2226,9 +2222,9 @@ double P3M_DIPOLAR_real_space_error(double box_size, double prefac, d_con = 1.0 / sqrt(box_size * box_size * box_size * d_a2 * d_a2 * d_rcut2 * d_rcut2 * d_rcut2 * d_rcut2 * d_RCUT * (double)n_c_part); - d_error_f = d_c * d_con * - sqrt((13. / 6.) * d_cc * d_cc + (2. / 15.) * d_dc * d_dc - - (13. / 15.) * d_cc * d_dc); + d_error_f = + d_c * d_con * sqrt((13. / 6.) * d_cc * d_cc + (2. / 15.) * d_dc * d_dc - + (13. / 15.) * d_cc * d_dc); return d_error_f; } @@ -2579,8 +2575,8 @@ void dp3m_compute_constants_energy_dipolar() { dp3m.energy_correction = -dp3m.sum_mu2 * (Ukp3m + Eself + 2. * PI / 3.); } - /*****************************************************************************/ +/*****************************************************************************/ - /*****************************************************************************/ +/*****************************************************************************/ #endif /* DP3M */ diff --git a/src/core/p3m-dipolar.hpp b/src/core/p3m-dipolar.hpp index 7a2cfd111c..51b1bcf975 100755 --- a/src/core/p3m-dipolar.hpp +++ b/src/core/p3m-dipolar.hpp @@ -155,8 +155,8 @@ void dp3m_count_magnetic_particles(); which may be smaller than 0, in which case the charge is assumed to be virtual and is not stored in the Dca_frac arrays. */ -void dp3m_assign_dipole(double const real_pos[3], double mu, double const dip[3], - int cp_cnt); +void dp3m_assign_dipole(double const real_pos[3], double mu, + double const dip[3], int cp_cnt); /** shrink wrap the dipoles grid */ void dp3m_shrink_wrap_dipole_grid(int n_dipoles); @@ -165,7 +165,8 @@ void dp3m_shrink_wrap_dipole_grid(int n_dipoles); If NPT is compiled in, it returns the energy, which is needed for NPT. */ inline double dp3m_add_pair_force(Particle *p1, Particle *p2, double *d, double dist2, double dist, double force[3]) { - if ((p1->p.dipm==0.) || (p2->p.dipm==0.)) return 0.; + if ((p1->p.dipm == 0.) || (p2->p.dipm == 0.)) + return 0.; int j; #ifdef NPT diff --git a/src/core/p3m.cpp b/src/core/p3m.cpp index 90793b655d..79da22becc 100755 --- a/src/core/p3m.cpp +++ b/src/core/p3m.cpp @@ -244,7 +244,7 @@ static void p3m_tune_aliasing_sums(int nx, int ny, int nz, int mesh[3], template static void p3m_do_charge_assign(); template -void p3m_do_assign_charge(double q, Vector3d& real_pos, int cp_cnt); +void p3m_do_assign_charge(double q, Vector3d &real_pos, int cp_cnt); /*@}*/ void p3m_pre_init(void) { @@ -354,16 +354,16 @@ void p3m_init() { p3m.recv_grid = Utils::realloc(p3m.recv_grid, sizeof(double) * p3m.sm.max); /* FFT */ - P3M_TRACE( - fprintf(stderr, "%d: p3m.rs_mesh ADR=%p\n", this_node, (void*) p3m.rs_mesh)); + P3M_TRACE(fprintf(stderr, "%d: p3m.rs_mesh ADR=%p\n", this_node, + (void *)p3m.rs_mesh)); int ca_mesh_size = fft_init(&p3m.rs_mesh, p3m.local_mesh.dim, p3m.local_mesh.margin, p3m.params.mesh, p3m.params.mesh_off, &p3m.ks_pnum); p3m.ks_mesh = Utils::realloc(p3m.ks_mesh, ca_mesh_size * sizeof(double)); - P3M_TRACE( - fprintf(stderr, "%d: p3m.rs_mesh ADR=%p\n", this_node, (void*) p3m.rs_mesh)); + P3M_TRACE(fprintf(stderr, "%d: p3m.rs_mesh ADR=%p\n", this_node, + (void *)p3m.rs_mesh)); /* k-space part: */ p3m_calc_differential_operator(); @@ -412,7 +412,6 @@ void p3m_set_tune_params(double r_cut, int mesh[3], int cao, double alpha, if (n_interpol != -1) p3m.params.inter = n_interpol; - } /*@}*/ @@ -565,7 +564,7 @@ template void p3m_do_charge_assign() { } /* Template wrapper for p3m_do_assign_charge() */ -void p3m_assign_charge(double q, Vector3d& real_pos, int cp_cnt) { +void p3m_assign_charge(double q, Vector3d &real_pos, int cp_cnt) { switch (p3m.params.cao) { case 1: p3m_do_assign_charge<1>(q, real_pos, cp_cnt); @@ -592,8 +591,8 @@ void p3m_assign_charge(double q, Vector3d& real_pos, int cp_cnt) { } template -void p3m_do_assign_charge(double q, Vector3d& real_pos, int cp_cnt) { - auto const inter = not (p3m.params.inter == 0); +void p3m_do_assign_charge(double q, Vector3d &real_pos, int cp_cnt) { + auto const inter = not(p3m.params.inter == 0); /* distance to nearest mesh point */ double dist[3]; /* index for caf interpolation grid */ @@ -611,8 +610,9 @@ void p3m_do_assign_charge(double q, Vector3d& real_pos, int cp_cnt) { for (int d = 0; d < 3; d++) { /* particle position in mesh coordinates */ - auto const pos = ((real_pos[d] - p3m.local_mesh.ld_pos[d]) * p3m.params.ai[d]) - - p3m.pos_shift; + auto const pos = + ((real_pos[d] - p3m.local_mesh.ld_pos[d]) * p3m.params.ai[d]) - + p3m.pos_shift; /* nearest mesh point */ auto const nmp = (int)pos; /* 3d-array index of nearest mesh point */ @@ -829,8 +829,9 @@ double p3m_calc_kspace_forces(int force_flag, int energy_flag) { for (i = 0; i < fft.plan[3].new_size; i++) { // Use the energy optimized influence function for energy! - node_k_space_energy += p3m.g_energy[i] * (Utils::sqr(p3m.rs_mesh[2 * i]) + - Utils::sqr(p3m.rs_mesh[2 * i + 1])); + node_k_space_energy += + p3m.g_energy[i] * + (Utils::sqr(p3m.rs_mesh[2 * i]) + Utils::sqr(p3m.rs_mesh[2 * i + 1])); } node_k_space_energy *= force_prefac; @@ -952,7 +953,8 @@ double p3m_calc_dipole_term(int force_flag, int energy_flag) { MPI_Allreduce(lcl_dm, gbl_dm, 3, MPI_DOUBLE, MPI_SUM, comm_cart); if (energy_flag) - en = 0.5 * pref * (Utils::sqr(gbl_dm[0]) + Utils::sqr(gbl_dm[1]) + Utils::sqr(gbl_dm[2])); + en = 0.5 * pref * (Utils::sqr(gbl_dm[0]) + Utils::sqr(gbl_dm[1]) + + Utils::sqr(gbl_dm[2])); else en = 0; if (force_flag) { @@ -1143,8 +1145,8 @@ inline double perform_aliasing_sums_force(int n[3], double numerator[3]) { nmz = p3m.meshift_z[n[KZ]] + p3m.params.mesh[RZ] * mz; sz = sy * int_pow<2 * cao>(sinc(nmz / (double)p3m.params.mesh[RZ])); - nm2 = - Utils::sqr(nmx / box_l[RX]) + Utils::sqr(nmy / box_l[RY]) + Utils::sqr(nmz / box_l[RZ]); + nm2 = Utils::sqr(nmx / box_l[RX]) + Utils::sqr(nmy / box_l[RY]) + + Utils::sqr(nmz / box_l[RZ]); expo = f1 * nm2; f2 = (expo < limit) ? sz * exp(-expo) / nm2 : 0.0; @@ -1177,9 +1179,9 @@ template void calc_influence_function_force() { /* Skip influence function calculation in tuning mode, the results need not be correct for timing. */ - if(p3m.params.tuning) { + if (p3m.params.tuning) { /* If resized, fill with zeros to avoid nan forces. */ - memset(p3m.g_force, 0, size * sizeof(double)); + memset(p3m.g_force, 0, size * sizeof(double)); return; } @@ -1207,10 +1209,9 @@ template void calc_influence_function_force() { Utils::sqr(p3m.d_op[RY][n[KY]] / box_l[RY]) + Utils::sqr(p3m.d_op[RZ][n[KZ]] / box_l[RZ]); - if(fak2 == 0) { + if (fak2 == 0) { fak3 = 0; - } - else + } else fak3 = fak1 / (fak2 * Utils::sqr(denominator)); p3m.g_force[ind] = 2 * fak3 / (PI); @@ -1269,8 +1270,8 @@ template inline double perform_aliasing_sums_energy(int n[3]) { nmz = p3m.meshift_z[n[KZ]] + p3m.params.mesh[RZ] * mz; sz = sy * int_pow<2 * cao>(sinc(nmz / (double)p3m.params.mesh[RZ])); /* k = 2*pi * (nx/lx, ny/ly, nz/lz); expo = -k^2 / 4*alpha^2 */ - nm2 = - Utils::sqr(nmx / box_l[RX]) + Utils::sqr(nmy / box_l[RY]) + Utils::sqr(nmz / box_l[RZ]); + nm2 = Utils::sqr(nmx / box_l[RX]) + Utils::sqr(nmy / box_l[RY]) + + Utils::sqr(nmz / box_l[RZ]); expo = f1 * nm2; f2 = (expo < limit) ? sz * exp(-expo) / nm2 : 0.0; @@ -1301,7 +1302,7 @@ template void calc_influence_function_energy() { /* Skip influence function calculation in tuning mode, the results need not be correct for timing. */ - if(p3m.params.tuning) + if (p3m.params.tuning) return; ind = 0; @@ -1746,8 +1747,7 @@ int p3m_adaptive_tune(char **log) { /* preparation */ mpi_bcast_event(P3M_COUNT_CHARGES); /* Print Status */ - sprintf(b, - "P3M tune parameters: Accuracy goal = %.5e prefactor = %.5e \n", + sprintf(b, "P3M tune parameters: Accuracy goal = %.5e prefactor = %.5e \n", p3m.params.accuracy, coulomb.prefactor); *log = strcat_alloc(*log, b); sprintf(b, "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", @@ -2315,7 +2315,11 @@ void p3m_scaleby_box_l() { void p3m_calc_kspace_stress(double *stress) { /** - Calculates the long range electrostatics part of the stress tensor. This is part Pi_{dir, alpha,beta} in the paper by Essmann et al "A smooth particle mesh Ewald method", The Journal of Chemical Physics 103, 8577 (1995); doi: 10.1063/1.470117. The part Pi_{corr, alpha, beta} in the Essmann paper is not present here since M is the empty set in our simulations. + Calculates the long range electrostatics part of the stress tensor. This is + part Pi_{dir, alpha,beta} in the paper by Essmann et al "A smooth particle + mesh Ewald method", The Journal of Chemical Physics 103, 8577 (1995); doi: + 10.1063/1.470117. The part Pi_{corr, alpha, beta} in the Essmann paper is not + present here since M is the empty set in our simulations. */ if (p3m.sum_q2 > 0) { double *node_k_space_stress; @@ -2352,12 +2356,13 @@ void p3m_calc_kspace_stress(double *stress) { } else { vterm = -2.0 * (1 / sqk + Utils::sqr(1.0 / 2.0 / p3m.params.alpha)); node_k_space_energy = - p3m.g_energy[ind] * - (Utils::sqr(p3m.rs_mesh[2 * ind]) + Utils::sqr(p3m.rs_mesh[2 * ind + 1])); + p3m.g_energy[ind] * (Utils::sqr(p3m.rs_mesh[2 * ind]) + + Utils::sqr(p3m.rs_mesh[2 * ind + 1])); } ind++; node_k_space_stress[0] += - node_k_space_energy * (1.0 + vterm * Utils::sqr(kx)); /* sigma_xx */ + node_k_space_energy * + (1.0 + vterm * Utils::sqr(kx)); /* sigma_xx */ node_k_space_stress[1] += node_k_space_energy * (vterm * kx * ky); /* sigma_xy */ node_k_space_stress[2] += @@ -2366,7 +2371,8 @@ void p3m_calc_kspace_stress(double *stress) { node_k_space_stress[3] += node_k_space_energy * (vterm * kx * ky); /* sigma_yx */ node_k_space_stress[4] += - node_k_space_energy * (1.0 + vterm * Utils::sqr(ky)); /* sigma_yy */ + node_k_space_energy * + (1.0 + vterm * Utils::sqr(ky)); /* sigma_yy */ node_k_space_stress[5] += node_k_space_energy * (vterm * ky * kz); /* sigma_yz */ @@ -2375,7 +2381,8 @@ void p3m_calc_kspace_stress(double *stress) { node_k_space_stress[7] += node_k_space_energy * (vterm * ky * kz); /* sigma_zy */ node_k_space_stress[8] += - node_k_space_energy * (1.0 + vterm * Utils::sqr(kz)); /* sigma_zz */ + node_k_space_energy * + (1.0 + vterm * Utils::sqr(kz)); /* sigma_zz */ } } } diff --git a/src/core/p3m.hpp b/src/core/p3m.hpp index 8bcd350161..4d9adde810 100755 --- a/src/core/p3m.hpp +++ b/src/core/p3m.hpp @@ -1,24 +1,24 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#ifndef _P3M_H +#ifndef _P3M_H #define _P3M_H /** \file p3m.hpp P3M algorithm for long range coulomb interaction. * @@ -26,12 +26,12 @@ * Ewald summation. Details of the used method can be found in * Hockney/Eastwood and Deserno/Holm. * - * Further reading: + * Further reading: *
    *
  • P.P. Ewald, * Die Berechnung optischer und elektrostatischer Gitterpotentiale, * Ann. Phys. (64) 253-287, 1921 - *
  • R. W. Hockney and J. W. Eastwood, + *
  • R. W. Hockney and J. W. Eastwood, * Computer Simulation Using Particles, * IOP, London, 1988 *
  • M. Deserno and C. Holm, @@ -44,16 +44,17 @@ *
  • M. Deserno, * Counterion condensation for rigid linear polyelectrolytes, * PhdThesis, Universit{\"a}t Mainz, 2000 - *
  • J.J. Cerda, P3M for dipolar interactions. J. Chem. Phys, 129, xxx ,(2008). + *
  • J.J. Cerda, P3M for dipolar interactions. J. Chem. Phys, 129, xxx + * ,(2008). *
*/ #include "config.hpp" -#include "utils.hpp" #include "debug.hpp" +#include "utils.hpp" -#include "p3m-common.hpp" #include "interaction_data.hpp" +#include "p3m-common.hpp" #ifdef P3M @@ -70,7 +71,7 @@ typedef struct { double *rs_mesh; /** k space mesh (local) for k space calculation and FFT.*/ double *ks_mesh; - + /** number of charged particles (only on master node). */ int sum_qpart; /** Sum of square of charges (only on master node). */ @@ -88,7 +89,8 @@ typedef struct { double *meshift_y; double *meshift_z; - /** Spatial differential operator in k-space. We use an i*k differentiation. */ + /** Spatial differential operator in k-space. We use an i*k differentiation. + */ double *d_op[3]; /** Force optimised influence function (k-space) */ double *g_force; @@ -108,10 +110,10 @@ typedef struct { int ks_pnum; /** send/recv mesh sizes */ - p3m_send_mesh sm; + p3m_send_mesh sm; /** Field to store grid points to send. */ - double *send_grid; + double *send_grid; /** Field to store grid points to recv */ double *recv_grid; } p3m_data_struct; @@ -127,7 +129,7 @@ void p3m_pre_init(void); int p3m_adaptive_tune(char **log); -/** Initialize all structures, parameters and arrays needed for the +/** Initialize all structures, parameters and arrays needed for the * P3M algorithm for charge-charge interactions. */ void p3m_init(void); @@ -136,11 +138,12 @@ void p3m_init(void); \ref p3m_parameter_struct::r_cut if \ref box_l changed. */ void p3m_scaleby_box_l(); -/** compute the k-space part of forces and energies for the charge-charge interaction **/ +/** compute the k-space part of forces and energies for the charge-charge + * interaction **/ double p3m_calc_kspace_forces(int force_flag, int energy_flag); /** computer the k-space part of the stress tensor **/ -void p3m_calc_kspace_stress (double* stress); +void p3m_calc_kspace_stress(double *stress); /// sanity checks int p3m_sanity_checks(); @@ -156,28 +159,38 @@ void p3m_count_charged_particles(); P3M_TUNE_ELCTEST: conflict with ELC gap size. */ -enum P3M_TUNE_ERROR { P3M_TUNE_FAIL = 1, P3M_TUNE_NOCUTOFF = 2, P3M_TUNE_CAOTOLARGE = 4, P3M_TUNE_ELCTEST = 8, P3M_TUNE_CUTOFF_TOO_LARGE = 16 }; +enum P3M_TUNE_ERROR { + P3M_TUNE_FAIL = 1, + P3M_TUNE_NOCUTOFF = 2, + P3M_TUNE_CAOTOLARGE = 4, + P3M_TUNE_ELCTEST = 8, + P3M_TUNE_CUTOFF_TOO_LARGE = 16 +}; /** Tune P3M parameters to desired accuracy. The parameters are tuned to obtain the desired accuracy in best time, by running mpi_integrate(0) for several parameter sets. - The function utilizes the analytic expression of the error estimate - for the P3M method in the book of Hockney and Eastwood (Eqn. 8.23) in - order to obtain the rms error in the force for a system of N randomly + The function utilizes the analytic expression of the error estimate + for the P3M method in the book of Hockney and Eastwood (Eqn. 8.23) in + order to obtain the rms error in the force for a system of N randomly distributed particles in a cubic box. - For the real space error the estimate of Kolafa/Perram is used. + For the real space error the estimate of Kolafa/Perram is used. - Parameter range if not given explicit values: For \ref p3m_parameter_struct::r_cut_iL + Parameter range if not given explicit values: For \ref + p3m_parameter_struct::r_cut_iL the function uses the values (\ref min_local_box_l -\ref #skin) / (n * \ref box_l), n being an integer (this implies the assumption that \ref - p3m_parameter_struct::r_cut_iL is the largest cutoff in the system!). For \ref - p3m_parameter_struct::mesh the function uses the two values which matches best the + p3m_parameter_struct::r_cut_iL is the largest cutoff in the system!). For + \ref + p3m_parameter_struct::mesh the function uses the two values which matches + best the equation: number of mesh point = number of charged particles. For \ref p3m_parameter_struct::cao the function considers all possible values. - For each setting \ref p3m_parameter_struct::alpha_L is calculated assuming that the + For each setting \ref p3m_parameter_struct::alpha_L is calculated assuming + that the error contributions of real and reciprocal space should be equal. After checking if the total error fulfils the accuracy goal the @@ -186,45 +199,52 @@ enum P3M_TUNE_ERROR { P3M_TUNE_FAIL = 1, P3M_TUNE_NOCUTOFF = 2, P3M_TUNE_CAOTOLA The function returns a log of the performed tuning. - The function is based on routines of the program HE_Q.cpp written by M. Deserno. + The function is based on routines of the program HE_Q.cpp written by M. + Deserno. */ /** assign the physical charges using the tabulated charge assignment function. - If store_ca_frac is true, then the charge fractions are buffered in cur_ca_fmp and + If store_ca_frac is true, then the charge fractions are buffered in + cur_ca_fmp and cur_ca_frac. */ void p3m_charge_assign(); -/** assign a single charge into the current charge grid. cp_cnt gives the a running index, - which may be smaller than 0, in which case the charge is assumed to be virtual and is not +/** assign a single charge into the current charge grid. cp_cnt gives the a + running index, + which may be smaller than 0, in which case the charge is assumed to be + virtual and is not stored in the ca_frac arrays. */ -void p3m_assign_charge(double q, - Vector3d& real_pos, - int cp_cnt); +void p3m_assign_charge(double q, Vector3d &real_pos, int cp_cnt); /** shrink wrap the charge grid */ void p3m_shrink_wrap_charge_grid(int n_charges); /** Calculate real space contribution of coulomb pair forces. If NPT is compiled in, it returns the energy, which is needed for NPT. */ -inline double p3m_add_pair_force(double chgfac, double *d,double dist2,double dist,double force[3]) -{ - if(dist < p3m.params.r_cut) { - if (dist > 0.0){ //Vincent +inline double p3m_add_pair_force(double chgfac, double *d, double dist2, + double dist, double force[3]) { + if (dist < p3m.params.r_cut) { + if (dist > 0.0) { // Vincent double adist = p3m.params.alpha * dist; #if USE_ERFC_APPROXIMATION double erfc_part_ri = AS_erfc_part(adist) / dist; - double fac1 = coulomb.prefactor * chgfac * exp(-adist*adist); - double fac2 = fac1 * (erfc_part_ri + 2.0*p3m.params.alpha*wupii) / dist2; + double fac1 = coulomb.prefactor * chgfac * exp(-adist * adist); + double fac2 = + fac1 * (erfc_part_ri + 2.0 * p3m.params.alpha * wupii) / dist2; #else erfc_part_ri = erfc(adist) / dist; double fac1 = coulomb.prefactor * chgfac; - double fac2 = fac1 * (erfc_part_ri + 2.0*p3m.params.alpha*wupii*exp(-adist*adist)) / dist2; + double fac2 = fac1 * + (erfc_part_ri + + 2.0 * p3m.params.alpha * wupii * exp(-adist * adist)) / + dist2; #endif - for(int j=0;j<3;j++) - force[j] += fac2 * d[j]; - ESR_TRACE(fprintf(stderr,"%d: RSE: Pair dist=%.3f: force (%.3e,%.3e,%.3e)\n",this_node, - dist,fac2*d[0],fac2*d[1],fac2*d[2])); + for (int j = 0; j < 3; j++) + force[j] += fac2 * d[j]; + ESR_TRACE( + fprintf(stderr, "%d: RSE: Pair dist=%.3f: force (%.3e,%.3e,%.3e)\n", + this_node, dist, fac2 * d[0], fac2 * d[1], fac2 * d[2])); #ifdef NPT return fac1 * erfc_part_ri; #endif @@ -233,11 +253,11 @@ inline double p3m_add_pair_force(double chgfac, double *d,double dist2,double di return 0.0; } -void p3m_set_tune_params(double r_cut, int mesh[3], int cao, - double alpha, double accuracy, int n_interpol); +void p3m_set_tune_params(double r_cut, int mesh[3], int cao, double alpha, + double accuracy, int n_interpol); -int p3m_set_params(double r_cut, int *mesh, int cao, - double alpha, double accuracy); +int p3m_set_params(double r_cut, int *mesh, int cao, double alpha, + double accuracy); int p3m_set_mesh_offset(double x, double y, double z); @@ -245,20 +265,18 @@ int p3m_set_eps(double eps); int p3m_set_ninterpol(int n); - /** Calculate real space contribution of coulomb pair energy. */ -inline double p3m_pair_energy(double chgfac, double dist) -{ +inline double p3m_pair_energy(double chgfac, double dist) { double adist, erfc_part_ri; - if(dist < p3m.params.r_cut && dist != 0) { + if (dist < p3m.params.r_cut && dist != 0) { adist = p3m.params.alpha * dist; #if USE_ERFC_APPROXIMATION erfc_part_ri = AS_erfc_part(adist) / dist; - return coulomb.prefactor*chgfac*erfc_part_ri*exp(-adist*adist); + return coulomb.prefactor * chgfac * erfc_part_ri * exp(-adist * adist); #else erfc_part_ri = erfc(adist) / dist; - return coulomb.prefactor*chgfac*erfc_part_ri; + return coulomb.prefactor * chgfac * erfc_part_ri; #endif } return 0.0; @@ -269,4 +287,4 @@ void p3m_free(); #endif /* of ifdef P3M */ -#endif /*of ifndef P3M_H */ +#endif /*of ifndef P3M_H */ diff --git a/src/core/p3m_gpu.cpp b/src/core/p3m_gpu.cpp index 5dce30720c..ff36432e46 100644 --- a/src/core/p3m_gpu.cpp +++ b/src/core/p3m_gpu.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "p3m_gpu.hpp" - +#include "config.hpp" diff --git a/src/core/p3m_gpu.hpp b/src/core/p3m_gpu.hpp index 24b89036b9..73f86aa206 100644 --- a/src/core/p3m_gpu.hpp +++ b/src/core/p3m_gpu.hpp @@ -1,25 +1,25 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _P3M_GPU_H #define _P3M_GPU_H -//NOTE :if one wants to use doubles it requires cuda compute capability 1.3 +// NOTE :if one wants to use doubles it requires cuda compute capability 1.3 #define _P3M_GPU_FLOAT //#define _P3M_GPU_REAL_DOUBLE @@ -45,4 +45,3 @@ void p3m_gpu_init(int cao, int mesh[3], double alpha); void p3m_gpu_add_farfield_force(); #endif /* _P3M_GPU_H */ - diff --git a/src/core/p3m_gpu_common.hpp b/src/core/p3m_gpu_common.hpp index c645410b04..be508b06c6 100644 --- a/src/core/p3m_gpu_common.hpp +++ b/src/core/p3m_gpu_common.hpp @@ -1,18 +1,18 @@ -/* +/* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -27,15 +27,9 @@ namespace { /** This function returns either fabs or fabsf depending on * the type of the argument via template specialization. */ -template -__device__ T myabs(T x) { - return fabs(x); -} +template __device__ T myabs(T x) { return fabs(x); } -template<> -__device__ float myabs(float x) { - return fabsf(x); -} +template <> __device__ float myabs(float x) { return fabsf(x); } /** * \brief Calculate integer powers. @@ -44,49 +38,42 @@ __device__ float myabs(float x) { * at compile time. It uses exponentiation by * squaring to construct a efficient function. */ -template -__device__ T int_pow(T x) { - switch(n) { - case 0: - return T(1); - case 1: - return x; - default: - /** Even branch */ - if(n % 2 == 0) { - return int_pow(x * x); - } else { - return x * int_pow<(n - 1)/2, T>(x * x); - } +template __device__ T int_pow(T x) { + switch (n) { + case 0: + return T(1); + case 1: + return x; + default: + /** Even branch */ + if (n % 2 == 0) { + return int_pow(x * x); + } else { + return x * int_pow<(n - 1) / 2, T>(x * x); + } } } -template -__device__ inline T csinc(T d) -{ +template __device__ inline T csinc(T d) { constexpr T epsi(0.1); - const T PId = PI*d; + const T PId = PI * d; - if (myabs(d)>epsi) - return sin(PId)/PId; + if (myabs(d) > epsi) + return sin(PId) / PId; else { /** Coefficients of the Taylor expansion of sinc */ constexpr T c2 = -0.1666666666667e-0; - constexpr T c4 = 0.8333333333333e-2; + constexpr T c4 = 0.8333333333333e-2; constexpr T c6 = -0.1984126984127e-3; - constexpr T c8 = 0.2755731922399e-5; - + constexpr T c8 = 0.2755731922399e-5; + const T PId2 = PId * PId; - return 1.0 + PId2*(c2+PId2*(c4+PId2*(c6+PId2*c8))); + return 1.0 + PId2 * (c2 + PId2 * (c4 + PId2 * (c6 + PId2 * c8))); } } -template -__device__ T sqr(T x) { - return x*x; -} - +template __device__ T sqr(T x) { return x * x; } } #endif diff --git a/src/core/p3m_gpu_error.hpp b/src/core/p3m_gpu_error.hpp index a592fe5ad9..1cda24d210 100644 --- a/src/core/p3m_gpu_error.hpp +++ b/src/core/p3m_gpu_error.hpp @@ -4,6 +4,7 @@ #include "config.hpp" #ifdef CUDA -double p3m_k_space_error_gpu(double prefactor, int *mesh, int cao, int npart, double sum_q2, double alpha_L, double *box); +double p3m_k_space_error_gpu(double prefactor, int *mesh, int cao, int npart, + double sum_q2, double alpha_L, double *box); #endif #endif diff --git a/src/core/pair_criteria/pair_criteria.hpp b/src/core/pair_criteria/pair_criteria.hpp index d7bca01388..2d54281bed 100644 --- a/src/core/pair_criteria/pair_criteria.hpp +++ b/src/core/pair_criteria/pair_criteria.hpp @@ -1,93 +1,83 @@ #ifndef PAIR_CRITERIA_HPP #define PAIR_CRITERIA_HPP -#include "particle_data.hpp" -#include "interaction_data.hpp" -#include "grid.hpp" #include "energy_inline.hpp" +#include "grid.hpp" +#include "interaction_data.hpp" +#include "particle_data.hpp" #include - - namespace PairCriteria { /** @brief Criterion which provides a true/false for a pair of particles */ class PairCriterion { - public: - /** @brief Make a decision based on two Particle objects */ - virtual bool decide(const Particle& p1, const Particle& p2) const =0; - /** @brief Make a decision based on particle ids. - * This can only run on the master node outside the integration loop */ - bool decide(int id1, int id2) const { - // Retrieve particle data - auto const &p1= get_particle_data(id1); - auto const &p2 = get_particle_data(id2); - const bool res = decide(p1, p2); - return res; - } - virtual ~PairCriterion() {} +public: + /** @brief Make a decision based on two Particle objects */ + virtual bool decide(const Particle &p1, const Particle &p2) const = 0; + /** @brief Make a decision based on particle ids. + * This can only run on the master node outside the integration loop */ + bool decide(int id1, int id2) const { + // Retrieve particle data + auto const &p1 = get_particle_data(id1); + auto const &p2 = get_particle_data(id2); + const bool res = decide(p1, p2); + return res; + } + virtual ~PairCriterion() {} }; -/** @brief True if two particles are closer than a cut off distance, respecting minimum image convention */ +/** @brief True if two particles are closer than a cut off distance, respecting + * minimum image convention */ class DistanceCriterion : public PairCriterion { - public: - bool decide(const Particle& p1, const Particle& p2) const override { - double vec21[3]; - get_mi_vector(vec21,p1.r.p, p2.r.p); - return sqrt(sqrlen(vec21))<= m_cut_off; - }; - double get_cut_off() { - return m_cut_off; - } - void set_cut_off(double c){ - m_cut_off =c; - } - private: - double m_cut_off; -}; +public: + bool decide(const Particle &p1, const Particle &p2) const override { + double vec21[3]; + get_mi_vector(vec21, p1.r.p, p2.r.p); + return sqrt(sqrlen(vec21)) <= m_cut_off; + }; + double get_cut_off() { return m_cut_off; } + void set_cut_off(double c) { m_cut_off = c; } +private: + double m_cut_off; +}; /** True if the short range energy is largern than a cut_off */ class EnergyCriterion : public PairCriterion { - public: - bool decide(const Particle& p1, const Particle& p2) const override { - // Distnace between particles - double vec21[3]; - get_mi_vector(vec21,p1.r.p, p2.r.p); - const double dist_betw_part =sqrt(sqrlen(vec21)); - - // Interaction parameters for particle types - IA_parameters *ia_params = get_ia_param(p1.p.type, p2.p.type); - - return (calc_non_bonded_pair_energy(&p1,&p2, ia_params, - vec21, dist_betw_part,dist_betw_part*dist_betw_part)) >= m_cut_off; - }; - double get_cut_off() { - return m_cut_off; - } - void set_cut_off(double c){ - m_cut_off =c; - } - private: - double m_cut_off; +public: + bool decide(const Particle &p1, const Particle &p2) const override { + // Distnace between particles + double vec21[3]; + get_mi_vector(vec21, p1.r.p, p2.r.p); + const double dist_betw_part = sqrt(sqrlen(vec21)); + + // Interaction parameters for particle types + IA_parameters *ia_params = get_ia_param(p1.p.type, p2.p.type); + + return (calc_non_bonded_pair_energy( + &p1, &p2, ia_params, vec21, dist_betw_part, + dist_betw_part * dist_betw_part)) >= m_cut_off; + }; + double get_cut_off() { return m_cut_off; } + void set_cut_off(double c) { m_cut_off = c; } + +private: + double m_cut_off; }; /** True if a bond of given type exists between the two particles */ class BondCriterion : public PairCriterion { - public: - bool decide(const Particle& p1, const Particle& p2) const override { - return pair_bond_exists_on(&p1,&p2,m_bond_type) || pair_bond_exists_on(&p2,&p1,m_bond_type); - }; - int get_bond_type() { - return m_bond_type; - }; - void set_bond_type(int t){ - m_bond_type =t; - } - private: - int m_bond_type; +public: + bool decide(const Particle &p1, const Particle &p2) const override { + return pair_bond_exists_on(&p1, &p2, m_bond_type) || + pair_bond_exists_on(&p2, &p1, m_bond_type); + }; + int get_bond_type() { return m_bond_type; }; + void set_bond_type(int t) { m_bond_type = t; } + +private: + int m_bond_type; }; } #endif - diff --git a/src/core/partCfg_global.hpp b/src/core/partCfg_global.hpp index 1cd2cb52f6..257e5db5ae 100644 --- a/src/core/partCfg_global.hpp +++ b/src/core/partCfg_global.hpp @@ -1,6 +1,6 @@ #ifndef CORE_PART_CFG_GLOBAL_HPP #define CORE_PART_CFG_GLOBAL_HPP - + #include "PartCfg.hpp" /** @@ -9,6 +9,6 @@ * Particle coordinates are unfolded. * For documentation see @class ParticleCache */ -PartCfg & partCfg(std::unique_ptr init = std::unique_ptr{}); +PartCfg &partCfg(std::unique_ptr init = std::unique_ptr{}); #endif diff --git a/src/core/particle_data.hpp b/src/core/particle_data.hpp index adbfad44ac..3327efa8da 100755 --- a/src/core/particle_data.hpp +++ b/src/core/particle_data.hpp @@ -695,7 +695,7 @@ int set_particle_q(int part, double q); @return ES_OK if particle existed */ int set_particle_mu_E(int part, double mu_E[3]); -void get_particle_mu_E(int part, double(&mu_E)[3]); +void get_particle_mu_E(int part, double (&mu_E)[3]); #endif /** Call only on the master node: set particle type. diff --git a/src/core/polymer.cpp b/src/core/polymer.cpp index 90c596f34f..a6c004b0cb 100755 --- a/src/core/polymer.cpp +++ b/src/core/polymer.cpp @@ -33,6 +33,7 @@ #include #include +#include "PartCfg.hpp" #include "communication.hpp" #include "constraints.hpp" #include "constraints/ShapeBasedConstraint.hpp" @@ -41,7 +42,6 @@ #include "grid.hpp" #include "integrate.hpp" #include "interaction_data.hpp" -#include "PartCfg.hpp" #include "polymer.hpp" #include "random.hpp" #include "utils.hpp" @@ -51,7 +51,7 @@ * --------- * *************************************************************/ -int mindist3(PartCfg & partCfg, int part_id, double r_catch, int *ids) { +int mindist3(PartCfg &partCfg, int part_id, double r_catch, int *ids) { int caught = 0; auto const r_catch2 = r_catch * r_catch; @@ -67,7 +67,7 @@ int mindist3(PartCfg & partCfg, int part_id, double r_catch, int *ids) { return caught; } -double mindist4(PartCfg & partCfg, double pos[3]) { +double mindist4(PartCfg &partCfg, double pos[3]) { if (partCfg.size() == 0) { return std::min(std::min(box_l[0], box_l[1]), box_l[2]); } @@ -96,14 +96,16 @@ double buf_mindist4(double pos[3], int n_add, double *add) { dy -= dround(dy / box_l[1]) * box_l[1]; dz = pos[2] - add[3 * i + 2]; dz -= dround(dz / box_l[2]) * box_l[2]; - mindist = std::min(mindist, Utils::sqr(dx) + Utils::sqr(dy) + Utils::sqr(dz)); + mindist = + std::min(mindist, Utils::sqr(dx) + Utils::sqr(dy) + Utils::sqr(dz)); } if (mindist < 30000.0) return (sqrt(mindist)); return (-1.0); } -int collision(PartCfg & partCfg, double pos[3], double shield, int n_add, double *add) { +int collision(PartCfg &partCfg, double pos[3], double shield, int n_add, + double *add) { if (mindist4(partCfg, pos) > shield && buf_mindist4(pos, n_add, add) > shield) return (0); return (1); @@ -136,10 +138,11 @@ int constraint_collision(double *p1, double *p2) { return 0; } -int polymerC(PartCfg & partCfg, int N_P, int MPC, double bond_length, int part_id, double *posed, - int mode, double shield, int max_try, double val_cM, int cM_dist, - int type_nM, int type_cM, int type_bond, double angle, - double angle2, double *posed2, int constr) { +int polymerC(PartCfg &partCfg, int N_P, int MPC, double bond_length, + int part_id, double *posed, int mode, double shield, int max_try, + double val_cM, int cM_dist, int type_nM, int type_cM, + int type_bond, double angle, double angle2, double *posed2, + int constr) { int p, n, cnt1, cnt2, max_cnt, bond_size, i; double phi, zz, rr; double pos[3]; @@ -158,7 +161,8 @@ int polymerC(PartCfg & partCfg, int N_P, int MPC, double bond_length, int part_i cnt1 = cnt2 = max_cnt = 0; for (p = 0; p < N_P; p++) { - if (p > 0) posed = nullptr; + if (p > 0) + posed = nullptr; for (cnt2 = 0; cnt2 < max_try; cnt2++) { /* place start monomer */ @@ -219,7 +223,8 @@ int polymerC(PartCfg & partCfg, int N_P, int MPC, double bond_length, int part_i if (constr == 0 || constraint_collision(pos, poly.data() + 3 * (n - 1)) == 0) { - if (mode == 1 || collision(partCfg, pos, shield, n, poly.data()) == 0) + if (mode == 1 || + collision(partCfg, pos, shield, n, poly.data()) == 0) break; if (mode == 0) { cnt1 = -1; @@ -321,15 +326,17 @@ int polymerC(PartCfg & partCfg, int N_P, int MPC, double bond_length, int part_i pos[2] = poz[2] + zz; } -// POLY_TRACE(/* printf("a=(%f,%f,%f) absa=%f M=(%f,%f,%f) c=(%f,%f,%f) absMc=%f -// a*c=%f)\n",a[0],a[1],a[2],sqrt(Utils::sqr(a[0])+Utils::sqr(a[1])+Utils::sqr(a[2])),M[0],M[1],M[2],c[0],c[1],c[2],sqrt(Utils::sqr(M[0]+c[0])+Utils::sqr(M[1]+c[1])+Utils::sqr(M[2]+c[2])),a[0]*c[0]+a[1]*c[1]+a[2]*c[2]) -// */); -// POLY_TRACE(/* printf("placed Monomer %d at -// (%f,%f,%f)\n",n,pos[0],pos[1],pos[2]) */); + // POLY_TRACE(/* printf("a=(%f,%f,%f) absa=%f M=(%f,%f,%f) + // c=(%f,%f,%f) absMc=%f + // a*c=%f)\n",a[0],a[1],a[2],sqrt(Utils::sqr(a[0])+Utils::sqr(a[1])+Utils::sqr(a[2])),M[0],M[1],M[2],c[0],c[1],c[2],sqrt(Utils::sqr(M[0]+c[0])+Utils::sqr(M[1]+c[1])+Utils::sqr(M[2]+c[2])),a[0]*c[0]+a[1]*c[1]+a[2]*c[2]) + // */); + // POLY_TRACE(/* printf("placed Monomer %d at + // (%f,%f,%f)\n",n,pos[0],pos[1],pos[2]) */); if (constr == 0 || constraint_collision(pos, poly.data() + 3 * (n - 1)) == 0) { - if (mode == 1 || collision(partCfg, pos, shield, n, poly.data()) == 0) + if (mode == 1 || + collision(partCfg, pos, shield, n, poly.data()) == 0) break; if (mode == 0) { cnt1 = -2; @@ -401,8 +408,8 @@ int polymerC(PartCfg & partCfg, int N_P, int MPC, double bond_length, int part_i return (std::max(max_cnt, cnt2)); } -int counterionsC(PartCfg & partCfg, int N_CI, int part_id, int mode, double shield, int max_try, - double val_CI, int type_CI) { +int counterionsC(PartCfg &partCfg, int N_CI, int part_id, int mode, + double shield, int max_try, double val_CI, int type_CI) { int n, cnt1, max_cnt; double pos[3]; @@ -436,25 +443,21 @@ int counterionsC(PartCfg & partCfg, int N_CI, int part_id, int mode, double shie return (std::max(max_cnt, cnt1)); } - - - - - -int diamondC(PartCfg & partCfg, double a, double bond_length, int MPC, int N_CI, double val_nodes, - double val_cM, double val_CI, int cM_dist, int nonet) { +int diamondC(PartCfg &partCfg, double a, double bond_length, int MPC, int N_CI, + double val_nodes, double val_cM, double val_CI, int cM_dist, + int nonet) { int i, j, k, part_id, bond[2], type_bond = 0, type_node = 0, type_cM = 1, type_nM = 1, type_CI = 2; double pos[3], off = bond_length / sqrt(3); double dnodes[8][3] = {{0, 0, 0}, {1, 1, 1}, {2, 2, 0}, {0, 2, 2}, {2, 0, 2}, {3, 3, 1}, {1, 3, 3}, {3, 1, 3}}; - int dchain[16][5] = { - {0, 1, +1, +1, +1}, {1, 2, +1, +1, -1}, {1, 3, -1, +1, +1}, - {1, 4, +1, -1, +1}, {2, 5, +1, +1, +1}, {3, 6, +1, +1, +1}, - {4, 7, +1, +1, +1}, {5, 0, +1, +1, -1}, {5, 3, +1, -1, +1}, - {5, 4, -1, +1, +1}, {6, 0, -1, +1, +1}, {6, 2, +1, -1, +1}, - {6, 4, +1, +1, -1}, {7, 0, +1, -1, +1}, {7, 2, -1, +1, +1}, - {7, 3, +1, +1, -1}}; + int dchain[16] + [5] = {{0, 1, +1, +1, +1}, {1, 2, +1, +1, -1}, {1, 3, -1, +1, +1}, + {1, 4, +1, -1, +1}, {2, 5, +1, +1, +1}, {3, 6, +1, +1, +1}, + {4, 7, +1, +1, +1}, {5, 0, +1, +1, -1}, {5, 3, +1, -1, +1}, + {5, 4, -1, +1, +1}, {6, 0, -1, +1, +1}, {6, 2, +1, -1, +1}, + {6, 4, +1, +1, -1}, {7, 0, +1, -1, +1}, {7, 2, -1, +1, +1}, + {7, 3, +1, +1, -1}}; part_id = 0; /* place 8 tetra-functional nodes */ @@ -513,8 +516,8 @@ int diamondC(PartCfg & partCfg, double a, double bond_length, int MPC, int N_CI, return (0); } -int icosaederC(PartCfg & partCfg, double ico_a, int MPC, int N_CI, double val_cM, double val_CI, - int cM_dist) { +int icosaederC(PartCfg &partCfg, double ico_a, int MPC, int N_CI, double val_cM, + double val_CI, int cM_dist) { int i, j, k, l, part_id, bond[2], type_bond = 0, type_cM = 0, type_nM = 1, type_CI = 2; double pos[3], pos_shift[3], vec[3], e_vec[3], vec_l, @@ -571,7 +574,8 @@ int icosaederC(PartCfg & partCfg, double ico_a, int MPC, int N_CI, double val_cM for (l = 0; l < 3; l++) vec[l] = (ico_coord[ico_NN[i][0]][l] - ico_coord[ico_NN[i][4]][l]) / 3.; - vec_l = sqrt(Utils::sqr(vec[0]) + Utils::sqr(vec[1]) + Utils::sqr(vec[2])); + vec_l = + sqrt(Utils::sqr(vec[0]) + Utils::sqr(vec[1]) + Utils::sqr(vec[2])); for (l = 0; l < 3; l++) e_vec[l] = vec[l] / vec_l; @@ -605,7 +609,8 @@ int icosaederC(PartCfg & partCfg, double ico_a, int MPC, int N_CI, double val_cM if (i < ico_NN[i][j]) { for (l = 0; l < 3; l++) vec[l] = (ico_coord[ico_NN[i][j]][l] - ico_coord[i][l]) / 3.; - vec_l = sqrt(Utils::sqr(vec[0]) + Utils::sqr(vec[1]) + Utils::sqr(vec[2])); + vec_l = + sqrt(Utils::sqr(vec[0]) + Utils::sqr(vec[1]) + Utils::sqr(vec[2])); for (l = 0; l < 3; l++) e_vec[l] = vec[l] / vec_l; diff --git a/src/core/polymer.hpp b/src/core/polymer.hpp index d90d296b93..82e2bafaf7 100755 --- a/src/core/polymer.hpp +++ b/src/core/polymer.hpp @@ -30,8 +30,8 @@ For more information on polymer, see \ref polymer.cpp "polymer.c" */ -#include "particle_data.hpp" #include "PartCfg.hpp" +#include "particle_data.hpp" /************************************************************* * Functions * @@ -99,9 +99,9 @@ int constraint_collision(double *p1, double *p2); case.
If val_cM \< 1e-10, the charge is assumed to be zero, and type_cM = type_nM. */ -int polymerC(PartCfg &, int N_P, int MPC, double bond_length, int part_id, double *posed, - int mode, double shield, int max_try, double val_cM, int cM_dist, - int type_nM, int type_cM, int type_FENE, double angle, +int polymerC(PartCfg &, int N_P, int MPC, double bond_length, int part_id, + double *posed, int mode, double shield, int max_try, double val_cM, + int cM_dist, int type_nM, int type_cM, int type_FENE, double angle, double angle2, double *posed2, int constr); /** C implementation of 'counterions \ [options]'. @@ -119,15 +119,16 @@ int polymerC(PartCfg &, int N_P, int MPC, double bond_length, int part_id, doubl (default to '2') @return Returns how often the attempt to place a particle failed in the worst case. */ -int counterionsC(PartCfg &, int N_CI, int part_id, int mode, double shield, int max_try, - double val_CI, int type_CI); +int counterionsC(PartCfg &, int N_CI, int part_id, int mode, double shield, + int max_try, double val_CI, int type_CI); /** C implementation of 'diamond \ \ \ [options]' */ -int diamondC(PartCfg &, double a, double bond_length, int MPC, int N_CI, double val_nodes, - double val_cM, double val_CI, int cM_dist, int nonet); +int diamondC(PartCfg &, double a, double bond_length, int MPC, int N_CI, + double val_nodes, double val_cM, double val_CI, int cM_dist, + int nonet); /** C implementation of 'icosaeder \ \ \ [options]' */ -int icosaederC(PartCfg &, double ico_a, int MPC, int N_CI, double val_cM, double val_CI, - int cM_dist); +int icosaederC(PartCfg &, double ico_a, int MPC, int N_CI, double val_cM, + double val_CI, int cM_dist); #endif diff --git a/src/core/polynom.cpp b/src/core/polynom.cpp index 872fac09dd..accbff3e19 100644 --- a/src/core/polynom.cpp +++ b/src/core/polynom.cpp @@ -1,3 +1,2 @@ -#include "config.hpp" #include "polynom.hpp" - +#include "config.hpp" diff --git a/src/core/polynom.hpp b/src/core/polynom.hpp index 72a09bf925..322fc22976 100755 --- a/src/core/polynom.hpp +++ b/src/core/polynom.hpp @@ -1,27 +1,29 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file polynom.hpp Datatypes and functions for polynomials. - Evaluation possible both as Taylor and Chebychev series. Note that the length of the - double list is equal to the order of the polynomial plus 1, so that Polynom->n does not give + Evaluation possible both as Taylor and Chebychev series. Note that the + length of the + double list is equal to the order of the polynomial plus 1, so that + Polynom->n does not give the order of the polynomial, but one more. */ #ifndef POLYNOM_H @@ -32,32 +34,32 @@ /** basically, a polynomial is just a list of coefficients */ typedef DoubleList Polynom; -/** evaluate the polynomial interpreted as a Taylor series via the Horner scheme */ -inline double evaluateAsTaylorSeriesAt(Polynom *series, double x) -{ - int cnt = series->n - 1; +/** evaluate the polynomial interpreted as a Taylor series via the Horner scheme + */ +inline double evaluateAsTaylorSeriesAt(Polynom *series, double x) { + int cnt = series->n - 1; double *c = series->e; - double r = c[cnt]; + double r = c[cnt]; while (--cnt >= 0) - r = r*x + c[cnt]; + r = r * x + c[cnt]; return r; } -/** evaluate the polynomial interpreted as a Chebychev series. Requires a series with at least +/** evaluate the polynomial interpreted as a Chebychev series. Requires a series + with at least three coefficients, i.e. no linear approximations! */ -inline double evaluateAsChebychevSeriesAt(Polynom *series, double x) -{ +inline double evaluateAsChebychevSeriesAt(Polynom *series, double x) { int j; double *c = series->e; double x2 = 2.0 * x; double dd = c[series->n - 1]; - double d = x2*dd + c[series->n - 2]; - for(j = series->n - 3; j >= 1; j--) { + double d = x2 * dd + c[series->n - 2]; + for (j = series->n - 3; j >= 1; j--) { double tmp = d; - d = x2*d - dd + c[j]; + d = x2 * d - dd + c[j]; dd = tmp; } - return x*d - dd + 0.5 * c[0]; + return x * d - dd + 0.5 * c[0]; } #endif diff --git a/src/core/pressure.cpp b/src/core/pressure.cpp index dcda601ff7..eca586fda6 100755 --- a/src/core/pressure.cpp +++ b/src/core/pressure.cpp @@ -1,62 +1,74 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file pressure.cpp Implementation of \ref pressure.hpp "pressure.h". */ -#include "pressure_inline.hpp" #include "cells.hpp" -#include "integrate.hpp" #include "initialize.hpp" -#include "virtual_sites.hpp" +#include "integrate.hpp" #include "npt.hpp" -#include "p3m.hpp" #include "p3m-dipolar.hpp" +#include "p3m.hpp" +#include "pressure_inline.hpp" +#include "virtual_sites.hpp" #include "short_range_loop.hpp" -Observable_stat virials = {0, {}, 0,0,0,0,0}; -Observable_stat total_pressure = {0, {}, 0,0,0,0,0}; -Observable_stat p_tensor = {0, {},0,0,0,0,0}; -Observable_stat total_p_tensor = {0, {},0,0,0,0,0}; +Observable_stat virials = {0, {}, 0, 0, 0, 0, 0}; +Observable_stat total_pressure = {0, {}, 0, 0, 0, 0, 0}; +Observable_stat p_tensor = {0, {}, 0, 0, 0, 0, 0}; +Observable_stat total_p_tensor = {0, {}, 0, 0, 0, 0, 0}; /* Observables used in the calculation of intra- and inter- molecular non-bonded contributions to pressure and to stress tensor */ -Observable_stat_non_bonded virials_non_bonded = {0, {}, 0,0,0}; -Observable_stat_non_bonded total_pressure_non_bonded = {0, {}, 0,0,0}; -Observable_stat_non_bonded p_tensor_non_bonded = {0, {},0,0,0}; -Observable_stat_non_bonded total_p_tensor_non_bonded = {0, {},0,0,0}; - -nptiso_struct nptiso = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,{0.0,0.0,0.0},{0.0,0.0,0.0},1, 0 ,{NPTGEOM_XDIR, NPTGEOM_YDIR, NPTGEOM_ZDIR},0,0,0}; +Observable_stat_non_bonded virials_non_bonded = {0, {}, 0, 0, 0}; +Observable_stat_non_bonded total_pressure_non_bonded = {0, {}, 0, 0, 0}; +Observable_stat_non_bonded p_tensor_non_bonded = {0, {}, 0, 0, 0}; +Observable_stat_non_bonded total_p_tensor_non_bonded = {0, {}, 0, 0, 0}; + +nptiso_struct nptiso = {0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + 1, + 0, + {NPTGEOM_XDIR, NPTGEOM_YDIR, NPTGEOM_ZDIR}, + 0, + 0, + 0}; /************************************************************/ /* callbacks for setmd */ /************************************************************/ - - /************************************************************/ /* local prototypes */ /************************************************************/ - + /** Calculate long range virials (P3M, MMM2d...). */ void calc_long_range_virials(); @@ -67,10 +79,10 @@ void init_virials(Observable_stat *stat); void init_virials_non_bonded(Observable_stat_non_bonded *stat_nb); /** on the master node: calc energies only if necessary - @param v_comp flag which enables (1) compensation of the velocities required - for deriving a pressure reflecting \ref nptiso_struct::p_inst - (hence it only works with domain decomposition); naturally it - therefore doesn't make sense to use it without NpT. */ + @param v_comp flag which enables (1) compensation of the velocities required + for deriving a pressure reflecting \ref nptiso_struct::p_inst + (hence it only works with domain decomposition); naturally it + therefore doesn't make sense to use it without NpT. */ void master_pressure_calc(int v_comp); /** Initializes stat to be used by \ref pressure_calc. */ @@ -83,10 +95,10 @@ void init_p_tensor_non_bonded(Observable_stat_non_bonded *stat_nb); /* Scalar and Tensorial Pressure */ /*********************************/ -void pressure_calc(double *result, double *result_t, double *result_nb, double *result_t_nb, int v_comp) -{ +void pressure_calc(double *result, double *result_t, double *result_nb, + double *result_t_nb, int v_comp) { int n, i; - double volume = box_l[0]*box_l[1]*box_l[2]; + double volume = box_l[0] * box_l[1] * box_l[2]; if (!interactions_sanity_checks()) return; @@ -94,7 +106,7 @@ void pressure_calc(double *result, double *result_t, double *result_nb, double * init_virials(&virials); init_p_tensor(&p_tensor); - + init_virials_non_bonded(&virials_non_bonded); init_p_tensor_non_bonded(&p_tensor_non_bonded); @@ -113,166 +125,192 @@ void pressure_calc(double *result, double *result_t, double *result_nb, double * #endif }, [](Particle &p1, Particle &p2, Distance &d) { - add_non_bonded_pair_virials(&(p1), &(p2), d.vec21.data(), sqrt(d.dist2), - d.dist2); + add_non_bonded_pair_virials(&(p1), &(p2), d.vec21.data(), sqrt(d.dist2), + d.dist2); }); -/* rescale kinetic energy (=ideal contribution) */ - virials.data.e[0] /= (3.0*volume*time_step*time_step); + /* rescale kinetic energy (=ideal contribution) */ + virials.data.e[0] /= (3.0 * volume * time_step * time_step); calc_long_range_virials(); #ifdef VIRTUAL_SITES - virtual_sites()->pressure_and_stress_tensor_contribution(virials.virtual_sites,p_tensor.virtual_sites); + virtual_sites()->pressure_and_stress_tensor_contribution( + virials.virtual_sites, p_tensor.virtual_sites); #endif - for (n = 1; n < virials.data.n; n++) - virials.data.e[n] /= 3.0*volume; + virials.data.e[n] /= 3.0 * volume; - - for(i=0; i<9; i++) - p_tensor.data.e[i] /= (volume*time_step*time_step); + for (i = 0; i < 9; i++) + p_tensor.data.e[i] /= (volume * time_step * time_step); - for(i=9; in_pressure_contribs(); + n_vs = virtual_sites()->n_pressure_contribs(); #endif - // Allocate memory for the data - obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, n_coulomb, n_dipolar, n_vs, 1); + obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, + n_coulomb, n_dipolar, n_vs, 1); stat->init_status = 0; } /************************************************************/ -void init_virials_non_bonded(Observable_stat_non_bonded *stat_nb) -{ +void init_virials_non_bonded(Observable_stat_non_bonded *stat_nb) { int n_non_bonded; - n_non_bonded = (max_seen_particle_type*(max_seen_particle_type+1))/2; + n_non_bonded = (max_seen_particle_type * (max_seen_particle_type + 1)) / 2; obsstat_realloc_and_clear_non_bonded(stat_nb, n_non_bonded, 1); stat_nb->init_status_nb = 0; @@ -280,51 +318,63 @@ void init_virials_non_bonded(Observable_stat_non_bonded *stat_nb) /* Initialize the p_tensor */ /***************************/ -void init_p_tensor(Observable_stat *stat) -{ - // Determine number of contribution for different interaction types - // bonded, nonbonded, coulomb, dipolar, rigid bodies - int n_pre, n_non_bonded, n_coulomb, n_dipolar,n_vs; - +void init_p_tensor(Observable_stat *stat) { + // Determine number of contribution for different interaction types + // bonded, nonbonded, coulomb, dipolar, rigid bodies + int n_pre, n_non_bonded, n_coulomb, n_dipolar, n_vs; - n_pre = 1; - n_non_bonded = (max_seen_particle_type*(max_seen_particle_type+1))/2; + n_pre = 1; + n_non_bonded = (max_seen_particle_type * (max_seen_particle_type + 1)) / 2; n_coulomb = 0; n_dipolar = 0; - n_vs=0; + n_vs = 0; #ifdef ELECTROSTATICS switch (coulomb.method) { - case COULOMB_NONE: n_coulomb = 0; break; + case COULOMB_NONE: + n_coulomb = 0; + break; case COULOMB_P3M_GPU: - case COULOMB_P3M: n_coulomb = 2; break; - default: n_coulomb = 1; + case COULOMB_P3M: + n_coulomb = 2; + break; + default: + n_coulomb = 1; } #endif - + #ifdef DIPOLES switch (coulomb.Dmethod) { - case DIPOLAR_NONE: n_dipolar = 0; break; - case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: n_dipolar = 0; break; - case DIPOLAR_DS: n_dipolar = 0; break; - case DIPOLAR_P3M: n_dipolar = 2; break; - default: n_dipolar = 0; + case DIPOLAR_NONE: + n_dipolar = 0; + break; + case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: + n_dipolar = 0; + break; + case DIPOLAR_DS: + n_dipolar = 0; + break; + case DIPOLAR_P3M: + n_dipolar = 2; + break; + default: + n_dipolar = 0; } #endif #ifdef VIRTUAL_SITES - n_vs=virtual_sites()->n_pressure_contribs(); + n_vs = virtual_sites()->n_pressure_contribs(); #endif - obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, n_coulomb, n_dipolar, n_vs, 9); + obsstat_realloc_and_clear(stat, n_pre, bonded_ia_params.size(), n_non_bonded, + n_coulomb, n_dipolar, n_vs, 9); stat->init_status = 0; } /***************************/ -void init_p_tensor_non_bonded(Observable_stat_non_bonded *stat_nb) -{ +void init_p_tensor_non_bonded(Observable_stat_non_bonded *stat_nb) { int n_nonbonded; - n_nonbonded = (max_seen_particle_type*(max_seen_particle_type+1))/2; + n_nonbonded = (max_seen_particle_type * (max_seen_particle_type + 1)) / 2; obsstat_realloc_and_clear_non_bonded(stat_nb, n_nonbonded, 9); stat_nb->init_status_nb = 0; @@ -332,107 +382,141 @@ void init_p_tensor_non_bonded(Observable_stat_non_bonded *stat_nb) /************************************************************/ void master_pressure_calc(int v_comp) { - if(v_comp) - mpi_gather_stats(3, total_pressure.data.e, total_p_tensor.data.e, total_pressure_non_bonded.data_nb.e, total_p_tensor_non_bonded.data_nb.e); + if (v_comp) + mpi_gather_stats(3, total_pressure.data.e, total_p_tensor.data.e, + total_pressure_non_bonded.data_nb.e, + total_p_tensor_non_bonded.data_nb.e); else - mpi_gather_stats(2, total_pressure.data.e, total_p_tensor.data.e, total_pressure_non_bonded.data_nb.e, total_p_tensor_non_bonded.data_nb.e); - - total_pressure.init_status = 1+v_comp; - total_p_tensor.init_status = 1+v_comp; - total_pressure_non_bonded.init_status_nb = 1+v_comp; - total_p_tensor_non_bonded.init_status_nb = 1+v_comp; + mpi_gather_stats(2, total_pressure.data.e, total_p_tensor.data.e, + total_pressure_non_bonded.data_nb.e, + total_p_tensor_non_bonded.data_nb.e); + + total_pressure.init_status = 1 + v_comp; + total_p_tensor.init_status = 1 + v_comp; + total_pressure_non_bonded.init_status_nb = 1 + v_comp; + total_p_tensor_non_bonded.init_status_nb = 1 + v_comp; } - /*****************************************************/ /* Routines for Local Stress Tensor */ /*****************************************************/ namespace { /** Calculates the remainder of a division */ - double drem_down(double a, double b) { return a - floor(a / b) * b; } +double drem_down(double a, double b) { return a - floor(a / b) * b; } -int getintersection(double pos1[3], double pos2[3],int given, int get, double value, double *answer, double box_size[3]) -{ - /*pos1 and pos2 are two particle positions. */ - /*given and get are integers from 0 to 2. 0 = x direction. 1 = y direction. 2 = z direction */ - /*there is a point on the line between the two particles p1 and p2 such that r[given]=value */ - /*this procedure returns the value of r[get] at that point */ +int getintersection(double pos1[3], double pos2[3], int given, int get, + double value, double *answer, double box_size[3]) { + /*pos1 and pos2 are two particle positions. */ + /*given and get are integers from 0 to 2. 0 = x direction. 1 = y direction. 2 + * = z direction */ + /*there is a point on the line between the two particles p1 and p2 such that + * r[given]=value */ + /*this procedure returns the value of r[get] at that point */ double p2r[3]; int i; - for (i=0;i<3;i++) { - p2r[i] = drem_down((pos2[i]-pos1[i])+box_size[i]/2.0,box_size[i])-box_size[i]/2.0; + for (i = 0; i < 3; i++) { + p2r[i] = drem_down((pos2[i] - pos1[i]) + box_size[i] / 2.0, box_size[i]) - + box_size[i] / 2.0; } - value = drem_down((value-pos1[given])+box_size[given]/2.0,box_size[given])-box_size[given]/2.0; - //PTENSOR_TRACE(fprintf(stderr,"%d: getintersection: p1 is %f %f %f p2 is %f %f %f p2r is %f %f %f newvalue is %f\n",this_node,pos1[0],pos1[1],pos1[2],pos2[0],pos2[1],pos2[2],p2r[0],p2r[1],p2r[2],value);); - - if ((value)*(p2r[given]) < -0.0001) { - runtimeErrorMsg() <<"analyze stress_profile: getintersection: intersection is not between the two given particles - " << value << " is not between " << 0.0 << " and " << p2r[given] << " and box size is " << box_size[given] << ", given is " << given << "\n"; - return 0; + value = drem_down((value - pos1[given]) + box_size[given] / 2.0, + box_size[given]) - + box_size[given] / 2.0; + // PTENSOR_TRACE(fprintf(stderr,"%d: getintersection: p1 is %f %f %f p2 is %f + // %f %f p2r is %f %f %f newvalue is + // %f\n",this_node,pos1[0],pos1[1],pos1[2],pos2[0],pos2[1],pos2[2],p2r[0],p2r[1],p2r[2],value);); + + if ((value) * (p2r[given]) < -0.0001) { + runtimeErrorMsg() << "analyze stress_profile: getintersection: " + "intersection is not between the two given particles " + "- " + << value << " is not between " << 0.0 << " and " + << p2r[given] << " and box size is " << box_size[given] + << ", given is " << given << "\n"; + return 0; } else if (given == get) { - *answer = drem_down(value + pos1[given],box_size[given]);; - } else if (0==p2r[given]) { - runtimeErrorMsg() <<"analyze stress_profile: getintersection: intersection is a line, not a point - value is " << value << " same as " << 0.0 << " and " << p2r[given] << "\n"; - return 0; + *answer = drem_down(value + pos1[given], box_size[given]); + ; + } else if (0 == p2r[given]) { + runtimeErrorMsg() << "analyze stress_profile: getintersection: " + "intersection is a line, not a point - value is " + << value << " same as " << 0.0 << " and " << p2r[given] + << "\n"; + return 0; } else { - *answer = drem_down(pos1[get]+p2r[get]/p2r[given]*value,box_size[get]); + *answer = + drem_down(pos1[get] + p2r[get] / p2r[given] * value, box_size[get]); } return 1; } -int getlength(double pos1[3], double pos2[3], int d1, double val1, int d2, double val2, int l, double *answer) -{ - /*p1 and p2 are two particles positions - d1 and d2 are integers between 0 and 2 denoting an axis (x, y, or z) - l and k are integers between 0 and 2 denoting an axis (x, y, or z) - two points on the line connecting these particles are defined by r[d1]=val1 and r[d2]=val2 - call these two points p3 and p4 (not program variables) +int getlength(double pos1[3], double pos2[3], int d1, double val1, int d2, + double val2, int l, double *answer) { + /*p1 and p2 are two particles positions + d1 and d2 are integers between 0 and 2 denoting an axis (x, y, or z) + l and k are integers between 0 and 2 denoting an axis (x, y, or z) + two points on the line connecting these particles are defined by r[d1]=val1 + and r[d2]=val2 + call these two points p3 and p4 (not program variables) this program returns the distance between p3 and p4 in the l direction */ - + double intersect1, intersect2; *answer = 0; - - if (! getintersection(pos1,pos2,d2,l,val2,&intersect1,box_l) || ! getintersection(pos1,pos2,d1,l,val1,&intersect2,box_l)) { + + if (!getintersection(pos1, pos2, d2, l, val2, &intersect1, box_l) || + !getintersection(pos1, pos2, d1, l, val1, &intersect2, box_l)) { return 0; } else { - *answer = drem_down(intersect2 - intersect1 + box_l[l]/2.0, box_l[l]) - box_l[l]/2.0; + *answer = drem_down(intersect2 - intersect1 + box_l[l] / 2.0, box_l[l]) - + box_l[l] / 2.0; return 1; } } -int does_line_go_through_cube(double pos1[3], double pos2[3], double range_start[3], double range[3], int sign[3], double entry[3], double exit[3],int *facein, int *faceout) - /* p1 and p2 are two particle positions - there is a cube in the simulation box with one vertex at range_start and the opposite vertex at range_start + range - this routine calculates where the line connecting p1 and p2 enters and exits this cube - these points are returned in the variables entry and exit - the function returns a 0 if the line does not pass through the cube and 1 if it does - */ +int does_line_go_through_cube(double pos1[3], double pos2[3], + double range_start[3], double range[3], + int sign[3], double entry[3], double exit[3], + int *facein, int *faceout) +/* p1 and p2 are two particle positions + there is a cube in the simulation box with one vertex at range_start and the + opposite vertex at range_start + range + this routine calculates where the line connecting p1 and p2 enters and exits + this cube + these points are returned in the variables entry and exit + the function returns a 0 if the line does not pass through the cube and 1 if + it does +*/ { - double centre[3]; /* centre of the cube */ - double vect2centre1[3]; /* vectors from centre of cube to pos1 and pos2 */ + double centre[3]; /* centre of the cube */ + double vect2centre1[3]; /* vectors from centre of cube to pos1 and pos2 */ double vect2centre2[3]; int i; - int doesntenter = 0; /* boolean that indicates whether we have already determined that the line does not enter the cube at all */ + int doesntenter = 0; /* boolean that indicates whether we have already + determined that the line does not enter the cube at + all */ double intersection1 = 0.0, intersection2 = 0.0; - int found_entry = 0; /* boolean that indicates whether we have determined where the line enters */ - int found_exit = 0; /* boolean that indicates whether we have determined where the line exits */ + int found_entry = 0; /* boolean that indicates whether we have determined + where the line enters */ + int found_exit = + 0; /* boolean that indicates whether we have determined where the line + exits */ int i1, i2; int inside1, inside2; - /* find centre of analyzed cube */ - for (i=0;i<3;i++) { - centre[i] = range_start[i] + range[i]/2.0; + /* find centre of analyzed cube */ + for (i = 0; i < 3; i++) { + centre[i] = range_start[i] + range[i] / 2.0; } /* find vectors connecting two particles to centre */ - get_mi_vector(vect2centre1,pos1,centre); - get_mi_vector(vect2centre2,pos2,centre); + get_mi_vector(vect2centre1, pos1, centre); + get_mi_vector(vect2centre2, pos2, centre); *facein = -1; *faceout = -1; @@ -440,37 +524,49 @@ int does_line_go_through_cube(double pos1[3], double pos2[3], double range_start /* check if particles are inside cube */ inside1 = 1; inside2 = 1; - for (i=0;i<3;i++) { - if (fabs(vect2centre1[i])>range[i]/2.0) inside1 = 0; - if (fabs(vect2centre2[i])>range[i]/2.0) inside2 = 0; + for (i = 0; i < 3; i++) { + if (fabs(vect2centre1[i]) > range[i] / 2.0) + inside1 = 0; + if (fabs(vect2centre2[i]) > range[i] / 2.0) + inside2 = 0; } - PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: Particle1 inside cube = %d Particle2 inside cube = %d \n",this_node,inside1,inside2);); + PTENSOR_TRACE(fprintf(stderr, "%d: does_line_go_through_cube: Particle1 " + "inside cube = %d Particle2 inside cube = %d " + "\n", + this_node, inside1, inside2);); /* work out which face connecting line enters through */ - if (! inside1) { - for (i=0;i<3;i++) { - i1 = (i+1)%3; - i2 = (i+2)%3; + if (!inside1) { + for (i = 0; i < 3; i++) { + i1 = (i + 1) % 3; + i2 = (i + 2) % 3; /*does the line start outside the cube in direction i?*/ - if ( (! doesntenter ) && (! found_entry) && fabs(vect2centre1[i])>range[i]/2.0 ) { - /*does the bond heads away from the cube or is part2 is before the cube in direction i? */ - if ((vect2centre1[i] * sign[i] > 0) || (vect2centre2[i]*sign[i] < -range[i]/2.0)) { - doesntenter = 1; - } else { - getintersection(vect2centre1, vect2centre2, i, i1, -range[i]/2.0*sign[i],&intersection1,box_l); - if (intersection1 > box_l[i1]/2) intersection1 -= box_l[i1]; - if (fabs(intersection1) < range[i1]/2.0) { - getintersection(vect2centre1, vect2centre2, i, i2, -range[i]/2.0*sign[i],&intersection2,box_l); - if (intersection2 > box_l[i2]/2) intersection2 -= box_l[i2]; - if (fabs(intersection2) < range[i2]/2.0) { - found_entry = 1; - entry[i] = centre[i] -range[i]/2.0*sign[i]; - entry[i1] = centre[i1] + intersection1; - entry[i2] = centre[i2] + intersection2; - *facein = i; - } - } - } + if ((!doesntenter) && (!found_entry) && + fabs(vect2centre1[i]) > range[i] / 2.0) { + /*does the bond heads away from the cube or is part2 is before the cube + * in direction i? */ + if ((vect2centre1[i] * sign[i] > 0) || + (vect2centre2[i] * sign[i] < -range[i] / 2.0)) { + doesntenter = 1; + } else { + getintersection(vect2centre1, vect2centre2, i, i1, + -range[i] / 2.0 * sign[i], &intersection1, box_l); + if (intersection1 > box_l[i1] / 2) + intersection1 -= box_l[i1]; + if (fabs(intersection1) < range[i1] / 2.0) { + getintersection(vect2centre1, vect2centre2, i, i2, + -range[i] / 2.0 * sign[i], &intersection2, box_l); + if (intersection2 > box_l[i2] / 2) + intersection2 -= box_l[i2]; + if (fabs(intersection2) < range[i2] / 2.0) { + found_entry = 1; + entry[i] = centre[i] - range[i] / 2.0 * sign[i]; + entry[i1] = centre[i1] + intersection1; + entry[i2] = centre[i2] + intersection2; + *facein = i; + } + } + } } } } else { @@ -478,162 +574,225 @@ int does_line_go_through_cube(double pos1[3], double pos2[3], double range_start entry[1] = pos1[1]; entry[2] = pos1[2]; } - if (! (found_entry) && ! (inside1)) { - PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: Line does not pass through cube \n",this_node);); + if (!(found_entry) && !(inside1)) { + PTENSOR_TRACE( + fprintf( + stderr, + "%d: does_line_go_through_cube: Line does not pass through cube \n", + this_node);); return 0; } else { - PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: Entry is %f %f %f \n",this_node,entry[0], entry[1], entry[2]);); - if (! inside2) { + PTENSOR_TRACE(fprintf(stderr, + "%d: does_line_go_through_cube: Entry is %f %f %f \n", + this_node, entry[0], entry[1], entry[2]);); + if (!inside2) { /*check which outside faces of box the line exits through */ - for (i=0;i<3;i++) { - i1 = (i+1)%3; - i2 = (i+2)%3; - /* does it enter into the box through the i face */ - if ((found_exit == 0) && (fabs(vect2centre2[i]) > range[i]/2.0)) { /*starts outside cube in i direction */ - getintersection(vect2centre1, vect2centre2, i, i1, range[i]/2.0*sign[i],&intersection1,box_l); - if (intersection1 > box_l[i1]/2) intersection1 -= box_l[i1]; - if (fabs(intersection1) < range[i1]/2.0) { - getintersection(vect2centre1, vect2centre2, i, i2, range[i]/2.0*sign[i],&intersection2,box_l); - if (intersection2 > box_l[i2]/2) intersection2 -= box_l[i2]; - if (fabs(intersection2) < range[i2]/2.0) { - found_exit = 1; - exit[i] = centre[i] + range[i]/2.0*sign[i]; - exit[i1] = centre[i1] + intersection1; - exit[i2] = centre[i2] + intersection2; - *faceout = i; - } - } - } + for (i = 0; i < 3; i++) { + i1 = (i + 1) % 3; + i2 = (i + 2) % 3; + /* does it enter into the box through the i face */ + if ((found_exit == 0) && + (fabs(vect2centre2[i]) > + range[i] / 2.0)) { /*starts outside cube in i direction */ + getintersection(vect2centre1, vect2centre2, i, i1, + range[i] / 2.0 * sign[i], &intersection1, box_l); + if (intersection1 > box_l[i1] / 2) + intersection1 -= box_l[i1]; + if (fabs(intersection1) < range[i1] / 2.0) { + getintersection(vect2centre1, vect2centre2, i, i2, + range[i] / 2.0 * sign[i], &intersection2, box_l); + if (intersection2 > box_l[i2] / 2) + intersection2 -= box_l[i2]; + if (fabs(intersection2) < range[i2] / 2.0) { + found_exit = 1; + exit[i] = centre[i] + range[i] / 2.0 * sign[i]; + exit[i1] = centre[i1] + intersection1; + exit[i2] = centre[i2] + intersection2; + *faceout = i; + } + } + } } } else { exit[0] = pos2[0]; exit[1] = pos2[1]; exit[2] = pos2[2]; } - PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: Exit is %f %f %f\n",this_node,exit[0], exit[1], exit[2]);); + PTENSOR_TRACE(fprintf(stderr, + "%d: does_line_go_through_cube: Exit is %f %f %f\n", + this_node, exit[0], exit[1], exit[2]);); } - PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: facein is %d faceout is %d\n",this_node,*facein,*faceout);); + PTENSOR_TRACE( + fprintf(stderr, + "%d: does_line_go_through_cube: facein is %d faceout is %d\n", + this_node, *facein, *faceout);); return 1; } -int distribute_tensors(DoubleList *TensorInBin, double *force, int bins[3], double range_start[3], double range[3], double pos1[3], double pos2[3]) -{ - /*calculates how to distribute a force tensor between two particles between various bins - the amount distributed to a bin is proportional to the length of the line between the +int distribute_tensors(DoubleList *TensorInBin, double *force, int bins[3], + double range_start[3], double range[3], double pos1[3], + double pos2[3]) { + /*calculates how to distribute a force tensor between two particles between + various bins + the amount distributed to a bin is proportional to the length of the line + between the two particles p1 and p2 that passes through the bin volume - we consider a cube of space starting with a corner at {x_range_start, y_range_start, z_range_start} extending to + we consider a cube of space starting with a corner at {x_range_start, + y_range_start, z_range_start} extending to {x_range_start+x_range, y_range_start+y_range, z_range_start+z_range} - this cube is split into x_bins bins in the x direction - we refer to these as x-bins + this cube is split into x_bins bins in the x direction - we refer to these + as x-bins each x-bin into y_bins bins in the y direction - we refer to these as y-bins each y_bin into z_bins bins in the z direction - we refer to these as z-bins */ - int sign[3],sign10[3]; /* indicates whether the line goes in the positive or negative direction in each dimension */ - double entry[3], exit[3]; /* the positions at which the line enters and exits the cube */ - int startx, endx; /* x-bins in which the line starts and ends in */ - int occupiedxbins; /* number of x-bins occuped by the line */ - int totoccupiedybins; /* total number of y-bins through which the line passes */ - int xbin, ybin, zbin; /* counters to keep track of bins x_bin goes from 0 to x_bins-1, y_bins from 0 to y_bins-1, z_bins from 0 to Z-bins-1 */ - int i ,k, l; - int counter; /* keeps track of where we are in the startz array */ - int zi; - double length; /* length of line between the two points */ - int d1,d2; /* for each z-bin d1 and d2 are calculated. they indicate through which faces of the bin the line enters and leaves the bin. i.e. if the line enters through the face corresponding to y = 0.34 then d1 = 1 (y-direction) and val1 = 0.34 */ + int sign[3], sign10 + [3]; /* indicates whether the line goes in the positive or + negative direction in each dimension */ + double entry[3], + exit[3]; /* the positions at which the line enters and exits the cube */ + int startx, endx; /* x-bins in which the line starts and ends in */ + int occupiedxbins; /* number of x-bins occuped by the line */ + int totoccupiedybins; /* total number of y-bins through which the line passes + */ + int xbin, ybin, + zbin; /* counters to keep track of bins x_bin goes from 0 to x_bins-1, + y_bins from 0 to y_bins-1, z_bins from 0 to Z-bins-1 */ + int i, k, l; + int counter; /* keeps track of where we are in the startz array */ + int zi; + double length; /* length of line between the two points */ + int d1, d2; /* for each z-bin d1 and d2 are calculated. they indicate through + which faces of the bin the line enters and leaves the bin. + i.e. if the line enters through the face corresponding to y = + 0.34 then d1 = 1 (y-direction) and val1 = 0.34 */ double val1, val2; double intersect; - double segment,segment2; - double calclength; - int xa, ya, za; /* counters for bins */ + double segment, segment2; + double calclength; + int xa, ya, za; /* counters for bins */ double temp[3]; - double redentry[3], redexit[3]; /* like entry and exit but using a coordinate system where range_start corresponds to (0,0,0) and the length scale in each direction is the bin width */ - double redbox_l[3]; /* box size is reduced units */ - int facein,faceout; - - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: Distributing tensors for particle p1 %f %f %f and p2 %f %f %f\n",this_node,pos1[0],pos1[1],pos1[2],pos2[0],pos2[1],pos2[2]);); - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: range_start is %f %f %f range is %f %f %f bins is %d %d %d\n",this_node,range_start[0],range_start[1],range_start[2],range[0],range[1],range[2],bins[0],bins[1],bins[2]);); + double redentry[3], + redexit + [3]; /* like entry and exit but using a coordinate system where + range_start corresponds to (0,0,0) and the length scale in + each direction is the bin width */ + double redbox_l[3]; /* box size is reduced units */ + int facein, faceout; + + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: Distributing tensors " + "for particle p1 %f %f %f and p2 %f %f %f\n", + this_node, pos1[0], pos1[1], pos1[2], pos2[0], pos2[1], + pos2[2]);); + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: range_start is %f %f " + "%f range is %f %f %f bins is %d %d %d\n", + this_node, range_start[0], range_start[1], + range_start[2], range[0], range[1], range[2], bins[0], + bins[1], bins[2]);); /* work out what direction the line joining the particles goes in */ length = 0; get_mi_vector(temp, pos2, pos1); - for (i=0;i<3;i++) { - sign[i] = (temp[i] > 0)*2-1; - sign10[i] = (sign[i]+1)/2.0; + for (i = 0; i < 3; i++) { + sign[i] = (temp[i] > 0) * 2 - 1; + sign10[i] = (sign[i] + 1) / 2.0; } - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: sign is %d %d %d\n",this_node,sign[0],sign[1],sign[2]);); - + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: sign is %d %d %d\n", + this_node, sign[0], sign[1], sign[2]);); + calclength = 0; - /* check if the line passes through the cube and if so where it enters and exits it */ - if (does_line_go_through_cube(pos1, pos2, range_start, range, sign, entry, exit,&facein,&faceout)) { - + /* check if the line passes through the cube and if so where it enters and + * exits it */ + if (does_line_go_through_cube(pos1, pos2, range_start, range, sign, entry, + exit, &facein, &faceout)) { + /* calculate reduced coordinates */ - /* range_start becomes (0,0,0) and range_start + range becomes (bins[0],bins[1],bins[2]) */ + /* range_start becomes (0,0,0) and range_start + range becomes + * (bins[0],bins[1],bins[2]) */ get_mi_vector(redentry, entry, range_start); get_mi_vector(redexit, exit, range_start); - for (i=0;i<3;i++) { - redentry[i] = drem_down(redentry[i]+box_l[i],box_l[i]); - redexit[i] = drem_down(redexit[i]+box_l[i],box_l[i]); + for (i = 0; i < 3; i++) { + redentry[i] = drem_down(redentry[i] + box_l[i], box_l[i]); + redexit[i] = drem_down(redexit[i] + box_l[i], box_l[i]); } length = 0; get_mi_vector(temp, exit, entry); - for (i=0;i<3;i++) { - redentry[i] = redentry[i]/range[i]*bins[i]; - redexit[i] = redexit[i]/range[i]*bins[i]; - length += pow(temp[i],2); + for (i = 0; i < 3; i++) { + redentry[i] = redentry[i] / range[i] * bins[i]; + redexit[i] = redexit[i] / range[i] * bins[i]; + length += pow(temp[i], 2); } - length = pow(length,0.5); - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: Reduced Entry is %f %f %f Reduced Exit is %f %f %f \n",this_node,redentry[0],redentry[1],redentry[2],redexit[0], redexit[1], redexit[2]);); - - for (i=0;i<3;i++) { - redbox_l[i] = box_l[i]/range[i]*bins[i]; + length = pow(length, 0.5); + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: Reduced Entry is %f " + "%f %f Reduced Exit is %f %f %f \n", + this_node, redentry[0], redentry[1], redentry[2], + redexit[0], redexit[1], redexit[2]);); + + for (i = 0; i < 3; i++) { + redbox_l[i] = box_l[i] / range[i] * bins[i]; } - - /* find in which x-bins the line starts and stops */ + + /* find in which x-bins the line starts and stops */ if (facein == 0) { startx = dround(redentry[0]) - 1 + sign10[0]; } else { startx = floor(redentry[0]); } - if ((startx < 0) && (range[0]==box_l[0])) startx += bins[0]; + if ((startx < 0) && (range[0] == box_l[0])) + startx += bins[0]; if (faceout == 0) { endx = dround(redexit[0] - sign10[0]); } else { endx = floor(redexit[0]); } - if ((endx < 0) && (range[0]==box_l[0])) startx += bins[0]; - occupiedxbins = (sign[0]*(endx-startx) + bins[0])%bins[0] +1; - - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: x goes from %d to %d\n",this_node,startx, endx);) + if ((endx < 0) && (range[0] == box_l[0])) + startx += bins[0]; + occupiedxbins = (sign[0] * (endx - startx) + bins[0]) % bins[0] + 1; + + PTENSOR_TRACE(fprintf(stderr, + "%d: distribute_tensors: x goes from %d to %d\n", + this_node, startx, endx);) /* Initialise starty array */ - std::vectorstarty(occupiedxbins+1); + std::vector starty(occupiedxbins + 1); std::vector occupiedybins(occupiedxbins); /* find in which y-bins the line starts and stops for each x-bin */ - /* in xbin the line starts in y-bin number starty[xbin-startx] and ends in starty[xbin-startx+1] */ + /* in xbin the line starts in y-bin number starty[xbin-startx] and ends in + * starty[xbin-startx+1] */ totoccupiedybins = 0; if (facein == 1) { starty[0] = dround(redentry[1]) - 1 + sign10[1]; } else { starty[0] = floor(redentry[1]); } - if ((starty[0] < 0) && (range[1]==box_l[1])) starty[0] += bins[1]; - for (xa=0; xa < occupiedxbins; xa++) { - xbin = (startx + xa*sign[0]+bins[0])%bins[0]; + if ((starty[0] < 0) && (range[1] == box_l[1])) + starty[0] += bins[1]; + for (xa = 0; xa < occupiedxbins; xa++) { + xbin = (startx + xa * sign[0] + bins[0]) % bins[0]; if (xbin == endx) { - intersect = redexit[1]; - if (faceout == 1) intersect -= sign10[1]; - if (( intersect < 0) && (range[1]==box_l[1])) intersect += bins[1]; + intersect = redexit[1]; + if (faceout == 1) + intersect -= sign10[1]; + if ((intersect < 0) && (range[1] == box_l[1])) + intersect += bins[1]; } else { - if (getintersection(redentry,redexit,0,1,xbin+sign10[0],&intersect,redbox_l) != 1) return 0; + if (getintersection(redentry, redexit, 0, 1, xbin + sign10[0], + &intersect, redbox_l) != 1) + return 0; } - starty[xa+1]=floor(intersect); - occupiedybins[xa] = ((starty[xa+1]-starty[xa])*sign[1]+bins[1])%bins[1]+1; + starty[xa + 1] = floor(intersect); + occupiedybins[xa] = + ((starty[xa + 1] - starty[xa]) * sign[1] + bins[1]) % bins[1] + 1; totoccupiedybins += occupiedybins[xa]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: in xbin %d y goes from %d to %d\n",this_node, xbin, starty[xa],starty[xa+1]);); + PTENSOR_TRACE( + fprintf(stderr, + "%d: distribute_tensors: in xbin %d y goes from %d to %d\n", + this_node, xbin, starty[xa], starty[xa + 1]);); } /* Initialise startz array */ std::vector occupiedzbins(totoccupiedybins); - std::vector startz(totoccupiedybins+1); + std::vector startz(totoccupiedybins + 1); /* find in which z-bins the line starts and stops for each y-bin*/ counter = 0; if (facein == 2) { @@ -641,173 +800,240 @@ int distribute_tensors(DoubleList *TensorInBin, double *force, int bins[3], doub } else { zi = floor(redentry[2]); } - if (( zi < 0) && (range[2]==box_l[2])) zi += bins[2]; + if ((zi < 0) && (range[2] == box_l[2])) + zi += bins[2]; startz[counter] = zi; - for (xa=0; xa < occupiedxbins; xa++) { - xbin = (startx + xa*sign[0]+bins[0])%bins[0]; - for (ya = 0; ya < occupiedybins[xa]-1; ya++) { - ybin = (starty[xa] + ya*sign[1] + bins[1])%bins[1]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: xbin is %d ya is %d, occupiedybins[xa] is %d, ybin is %d\n",this_node,xbin,ya,occupiedybins[xa],ybin);); - if (getintersection(redentry,redexit,1,2,ybin+sign10[1],&intersect,redbox_l) != 1) return 0; - zi = floor(intersect); - startz[counter+1] = zi; - occupiedzbins[counter]= (sign[2]*(startz[counter+1]-startz[counter]) + bins[2])%bins[2] +1; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: in xbin %d ybin %d zbin goes from %d to %d\n",this_node,xbin,ybin,startz[counter],startz[counter+1]);); - counter ++; + for (xa = 0; xa < occupiedxbins; xa++) { + xbin = (startx + xa * sign[0] + bins[0]) % bins[0]; + for (ya = 0; ya < occupiedybins[xa] - 1; ya++) { + ybin = (starty[xa] + ya * sign[1] + bins[1]) % bins[1]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: xbin is %d ya " + "is %d, occupiedybins[xa] is %d, ybin is " + "%d\n", + this_node, xbin, ya, occupiedybins[xa], ybin);); + if (getintersection(redentry, redexit, 1, 2, ybin + sign10[1], + &intersect, redbox_l) != 1) + return 0; + zi = floor(intersect); + startz[counter + 1] = zi; + occupiedzbins[counter] = + (sign[2] * (startz[counter + 1] - startz[counter]) + bins[2]) % + bins[2] + + 1; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: in xbin %d ybin " + "%d zbin goes from %d to %d\n", + this_node, xbin, ybin, startz[counter], + startz[counter + 1]);); + counter++; } - ybin = starty[xa+1]; + ybin = starty[xa + 1]; if (xbin == endx) { - if (faceout == 2) { - zi = dround(redexit[2] -sign10[2]); - } else { - zi = floor(redexit[2]); - } - if (( zi < 0) && (range[2]==box_l[2])) zi += bins[2]; - + if (faceout == 2) { + zi = dround(redexit[2] - sign10[2]); + } else { + zi = floor(redexit[2]); + } + if ((zi < 0) && (range[2] == box_l[2])) + zi += bins[2]; + } else { - if (getintersection(redentry,redexit,0,2,xbin+sign10[0], &intersect, redbox_l) != 1) return 0; - zi = floor(intersect); + if (getintersection(redentry, redexit, 0, 2, xbin + sign10[0], + &intersect, redbox_l) != 1) + return 0; + zi = floor(intersect); } - startz[counter+1]=zi; - occupiedzbins[counter]= (sign[2]*(startz[counter+1]-startz[counter]) + bins[2])%bins[2] +1; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: in xbin %d ybin %d zbin goes from %d to %d\n",this_node,xbin,ybin,startz[counter],startz[counter+1]);); - counter ++; + startz[counter + 1] = zi; + occupiedzbins[counter] = + (sign[2] * (startz[counter + 1] - startz[counter]) + bins[2]) % + bins[2] + + 1; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: in xbin %d ybin " + "%d zbin goes from %d to %d\n", + this_node, xbin, ybin, startz[counter], + startz[counter + 1]);); + counter++; } - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: occupiedxbins is %d,occupiedybins[0] is %d, occupiedzbins[0] is %d\n",this_node,occupiedxbins,occupiedybins[0],occupiedzbins[0]);); + PTENSOR_TRACE( + fprintf(stderr, "%d: distribute_tensors: occupiedxbins is " + "%d,occupiedybins[0] is %d, occupiedzbins[0] is %d\n", + this_node, occupiedxbins, occupiedybins[0], occupiedzbins[0]);); /* find out what length of the line passes through each z-bin */ counter = 0; - for (xa = 0; xa < occupiedxbins; xa ++) { - xbin = (startx + xa*sign[0]+bins[0])%bins[0]; + for (xa = 0; xa < occupiedxbins; xa++) { + xbin = (startx + xa * sign[0] + bins[0]) % bins[0]; for (ya = 0; ya < occupiedybins[xa]; ya++) { - ybin = (starty[xa] + ya*sign[1] + bins[1])%bins[1]; - for (za = 0; za < occupiedzbins[counter]; za++) { - zbin = (startz[counter] + za*sign[2] +bins[2])%bins[2]; - if (zbin == startz[counter]) { - if (ybin == starty[xa]) { - if (xbin == startx) { - if (entry[0]-exit[0] != 0) { - d1 = 0; - val1 = redentry[0]; - } else if (entry[1]-exit[1] != 0){ - d1 = 1; - val1 = redentry[1]; - } else { - d1 = 2; - val1 = redentry[2]; - } - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line starts at point p1 inside bin\n",this_node,xbin,ybin,zbin);); - } else { - d1 = 0; - val1 = xbin+1-sign10[0]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line enters through x = %e face of box\n",this_node,xbin,ybin,zbin,val1);); - } - } else { - d1 = 1; - val1 = ybin+1-sign10[1]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line enters through y = %e face of box\n",this_node,xbin,ybin,zbin,val1);); - } - } else { - d1 = 2; - val1 = zbin+1-sign10[2]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line enters through z = %e face of box zbin is %d\n",this_node,xbin,ybin,zbin,val1,zbin);); - } - if (zbin == startz[counter+1]) { - if (ybin == starty[xa+1]) { - if (xbin == endx) { - if (entry[0]-exit[0] != 0) { - d2 = 0; - val2 = redexit[0]; - } else if (entry[1]-exit[1]!= 0){ - d2 = 1; - val2 = redexit[1]; - } else { - d2 = 2; - val2 = redexit[2]; - } - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line ends at p2 inside bin\n",this_node,xbin,ybin,zbin);); - } - else { - d2 = 0; - val2 = xbin+sign10[0]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line leaves through x = %e face of box\n",this_node,xbin,ybin,zbin,val2);); - } - } - else { - d2 = 1; - val2 = ybin+sign10[1]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line leaves through y = %e face of box direction %d\n",this_node,xbin,ybin,zbin,val2,sign[1]);); - } - } - else { - d2= 2; - val2 = zbin+sign10[2]; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: %d %d %d line leaves through z = %e face of box\n",this_node,xbin,ybin,zbin,val2);); + ybin = (starty[xa] + ya * sign[1] + bins[1]) % bins[1]; + for (za = 0; za < occupiedzbins[counter]; za++) { + zbin = (startz[counter] + za * sign[2] + bins[2]) % bins[2]; + if (zbin == startz[counter]) { + if (ybin == starty[xa]) { + if (xbin == startx) { + if (entry[0] - exit[0] != 0) { + d1 = 0; + val1 = redentry[0]; + } else if (entry[1] - exit[1] != 0) { + d1 = 1; + val1 = redentry[1]; + } else { + d1 = 2; + val1 = redentry[2]; + } + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d " + "%d line starts at point p1 " + "inside bin\n", + this_node, xbin, ybin, zbin);); + } else { + d1 = 0; + val1 = xbin + 1 - sign10[0]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d " + "%d line enters through x = %e " + "face of box\n", + this_node, xbin, ybin, zbin, val1);); + } + } else { + d1 = 1; + val1 = ybin + 1 - sign10[1]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d %d " + "line enters through y = %e face " + "of box\n", + this_node, xbin, ybin, zbin, val1);); + } + } else { + d1 = 2; + val1 = zbin + 1 - sign10[2]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d %d " + "line enters through z = %e face of " + "box zbin is %d\n", + this_node, xbin, ybin, zbin, val1, zbin);); + } + if (zbin == startz[counter + 1]) { + if (ybin == starty[xa + 1]) { + if (xbin == endx) { + if (entry[0] - exit[0] != 0) { + d2 = 0; + val2 = redexit[0]; + } else if (entry[1] - exit[1] != 0) { + d2 = 1; + val2 = redexit[1]; + } else { + d2 = 2; + val2 = redexit[2]; + } + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d " + "%d line ends at p2 inside bin\n", + this_node, xbin, ybin, zbin);); + } else { + d2 = 0; + val2 = xbin + sign10[0]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d " + "%d line leaves through x = %e " + "face of box\n", + this_node, xbin, ybin, zbin, val2);); + } + } else { + d2 = 1; + val2 = ybin + sign10[1]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d %d " + "line leaves through y = %e face " + "of box direction %d\n", + this_node, xbin, ybin, zbin, val2, + sign[1]);); + } + } else { + d2 = 2; + val2 = zbin + sign10[2]; + PTENSOR_TRACE(fprintf(stderr, "%d: distribute_tensors: %d %d %d " + "line leaves through z = %e face of " + "box\n", + this_node, xbin, ybin, zbin, val2);); + } + segment2 = 0; + PTENSOR_TRACE( + fprintf(stderr, "%d: distribute_tensors: entry %f %f %f exit %f " + "%f %f d1 %d val1 %f d2 %d val2 %f\n", + this_node, entry[0], entry[1], entry[2], exit[0], exit[1], + exit[2], d1, + range_start[d1] + val1 * range[d1] / (double)bins[d1], d2, + range_start[d2] + val2 * range[d2] / (double)bins[d2]);); + for (l = 0; l < 3; l++) { + if (getlength(entry, exit, d1, + range_start[d1] + val1 * range[d1] / (double)bins[d1], + d2, + range_start[d2] + val2 * range[d2] / (double)bins[d2], + l, &segment) != 1) + return 0; + segment2 += pow(segment, 2); + for (k = 0; k < 3; k++) { + TensorInBin[xbin * bins[1] * bins[2] + ybin * bins[2] + zbin] + .e[3 * k + l] += force[k] * segment; + } + } + calclength += pow(segment2, 0.5); } - segment2 = 0; - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: entry %f %f %f exit %f %f %f d1 %d val1 %f d2 %d val2 %f\n",this_node,entry[0],entry[1],entry[2],exit[0],exit[1],exit[2],d1,range_start[d1]+val1*range[d1]/(double)bins[d1],d2,range_start[d2]+val2*range[d2]/(double)bins[d2]);); - for (l=0;l<3;l++) { - if (getlength(entry,exit,d1,range_start[d1]+val1*range[d1]/(double)bins[d1],d2,range_start[d2]+val2*range[d2]/(double)bins[d2],l,&segment) != 1) return 0; - segment2 += pow(segment,2); - for (k=0;k<3;k++) { - TensorInBin[xbin*bins[1]*bins[2]+ybin*bins[2]+zbin].e[3*k+l] += force[k] * segment; - } - } - calclength += pow(segment2,0.5); - } - counter ++; + counter++; } } - PTENSOR_TRACE(fprintf(stderr,"%d: distribute_tensors: calclength is %e and length is %e\n}",this_node,calclength,length);); - - if (calclength - length >0.0000000001) { - runtimeErrorMsg() << this_node << ": analyze stress_profile: bug in distribute tensor code - calclength is " << calclength << " and length is " << length; + PTENSOR_TRACE( + fprintf(stderr, + "%d: distribute_tensors: calclength is %e and length is %e\n}", + this_node, calclength, length);); + + if (calclength - length > 0.0000000001) { + runtimeErrorMsg() << this_node + << ": analyze stress_profile: bug in distribute tensor " + "code - calclength is " + << calclength << " and length is " << length; return 0; } } return 1; -} +} -int reducepos(double pos[3], int bins[3], double centre[3], double range[3], int reducedpos[3]) { +int reducepos(double pos[3], int bins[3], double centre[3], double range[3], + int reducedpos[3]) { int i; double working[3]; get_mi_vector(working, pos, centre); - for (i=0;i<3;i++) { - reducedpos[i] = floor((working[i]+range[i]/2.0)*(double)bins[i]/range[i]); + for (i = 0; i < 3; i++) { + reducedpos[i] = + floor((working[i] + range[i] / 2.0) * (double)bins[i] / range[i]); } - return 1; + return 1; } -int incubewithskin(double pos[3], double centre[3], double range[3]) -{ +int incubewithskin(double pos[3], double centre[3], double range[3]) { double working[3]; int i; get_mi_vector(working, pos, centre); - for (i=0; i <3; i++) { - if (fabs(working[i]) > range[i]/2.0 + skin+max_cut) return 0; + for (i = 0; i < 3; i++) { + if (fabs(working[i]) > range[i] / 2.0 + skin + max_cut) + return 0; } - return 1; + return 1; } -int whichbin(double pos[3], int bins[3], double centre[3], double range[3], int *bin) +int whichbin(double pos[3], int bins[3], double centre[3], double range[3], + int *bin) /*calculates which bin a particle is in for local_stress_tensor */ { int reducedpos[3]; int i; reducepos(pos, bins, centre, range, reducedpos); - for (i=0;i<3;i++) { + for (i = 0; i < 3; i++) { if ((reducedpos[i] < 0) || (reducedpos[i] >= bins[i])) { *bin = -1; return 1; } } - *bin = reducedpos[0]*bins[1]*bins[2] + reducedpos[1]*bins[2] + reducedpos[2]; + *bin = reducedpos[0] * bins[1] * bins[2] + reducedpos[1] * bins[2] + + reducedpos[2]; return 1; } -int get_nonbonded_interaction(Particle *p1, Particle *p2, double *force, Distance &) -{ +int get_nonbonded_interaction(Particle *p1, Particle *p2, double *force, + Distance &) { /* returns the non_bonded interaction between two particles */ double dist2, dist; @@ -817,47 +1043,53 @@ int get_nonbonded_interaction(Particle *p1, Particle *p2, double *force, Distanc double eforce[3]; #endif - force[0]=0; force[1]=0; force[2]=0; - + force[0] = 0; + force[1] = 0; + force[2] = 0; - if ((p1->p.identity != p2->p.identity)&&(checkIfParticlesInteract(p1->p.type, p2->p.type))) { + if ((p1->p.identity != p2->p.identity) && + (checkIfParticlesInteract(p1->p.type, p2->p.type))) { /* distance calculation */ get_mi_vector(d, p1->r.p, p2->r.p); dist2 = Utils::sqr(d[0]) + Utils::sqr(d[1]) + Utils::sqr(d[2]); - dist = sqrt(dist2); - calc_non_bonded_pair_force(p1,p2,d,dist,dist2,force); + dist = sqrt(dist2); + calc_non_bonded_pair_force(p1, p2, d, dist, dist2, force); #ifdef ELECTROSTATICS if (coulomb.method != COULOMB_NONE) { switch (coulomb.method) { #ifdef P3M case COULOMB_P3M_GPU: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle GPU P3M electrostatics so it is left out\n"); - break; + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle GPU P3M electrostatics so it is left out\n"); + break; case COULOMB_P3M: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle P3M electrostatics so it is left out\n"); - break; + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle P3M electrostatics so it is left out\n"); + break; #endif case COULOMB_DH: - for (i = 0; i < 3; i++) - eforce[i] = 0; - add_dh_coulomb_pair_force(p1,p2,d,dist, eforce); - for(i=0;i<3;i++) - force[i] += eforce[i]; - break; + for (i = 0; i < 3; i++) + eforce[i] = 0; + add_dh_coulomb_pair_force(p1, p2, d, dist, eforce); + for (i = 0; i < 3; i++) + force[i] += eforce[i]; + break; case COULOMB_RF: - for (i = 0; i < 3; i++) - eforce[i] = 0; - add_rf_coulomb_pair_force(p1,p2,d,dist, eforce); - for(i=0;i<3;i++) - force[i] += eforce[i]; - break; + for (i = 0; i < 3; i++) + eforce[i] = 0; + add_rf_coulomb_pair_force(p1, p2, d, dist, eforce); + for (i = 0; i < 3; i++) + force[i] += eforce[i]; + break; case COULOMB_INTER_RF: // this is done elsewhere - break; + break; case COULOMB_MMM1D: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle MMM1D electrostatics so it is left out\n"); + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle MMM1D electrostatics so it is left out\n"); default: - fprintf(stderr,"WARNING: Local stress tensor calculation does not recognise this electrostatic interaction\n"); + fprintf(stderr, "WARNING: Local stress tensor calculation does not " + "recognise this electrostatic interaction\n"); } } #endif /*ifdef ELECTROSTATICS */ @@ -867,23 +1099,27 @@ int get_nonbonded_interaction(Particle *p1, Particle *p2, double *force, Distanc switch (coulomb.Dmethod) { #ifdef DP3M case DIPOLAR_P3M: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle P3M magnetostatics so it is left out\n"); - break; + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle P3M magnetostatics so it is left out\n"); + break; #endif case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle DAWAANR magnetostatics so it is left out\n"); - break; + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle DAWAANR magnetostatics so it is left out\n"); + break; case DIPOLAR_DS: - fprintf(stderr,"WARNING: Local stress tensor calculation cannot handle MAGNETIC DIPOLAR SUM magnetostatics so it is left out\n"); - break; + fprintf(stderr, "WARNING: Local stress tensor calculation cannot " + "handle MAGNETIC DIPOLAR SUM magnetostatics so it is " + "left out\n"); + break; default: - fprintf(stderr,"WARNING: Local stress tensor calculation does not recognise this magnetostatic interaction\n"); + fprintf(stderr, "WARNING: Local stress tensor calculation does not " + "recognise this magnetostatic interaction\n"); } } #endif /*ifdef DIPOLES */ - } /*if p1-> ... */ return 0; } @@ -953,32 +1189,32 @@ int local_stress_tensor_calc(DoubleList *TensorInBin, int bins[3], } }; - auto add_bonded = - [&](Particle &p) { - int j = 0; - while (j < p.bl.n) { - auto type_num = p.bl.e[j++]; - auto iaparams = &bonded_ia_params[type_num]; - - /* fetch particle 2 */ - auto p2 = local_particles[p.bl.e[j++]]; - double dx[3]; - get_mi_vector(dx, p.r.p, p2->r.p); - std::array force; - calc_bonded_force(&p, p2, iaparams, &j, dx, force.data()); - PTENSOR_TRACE( - fprintf(stderr, "%d: Bonded to particle %d with force %f %f %f\n", - this_node, p2->p.identity, force[0], force[1], force[2])); - if ((pow(force[0], 2) + pow(force[1], 2) + pow(force[2], 2)) > 0) { - if (distribute_tensors(TensorInBin, force.data(), bins, range_start, range, - p.r.p.data(), p2->r.p.data()) != 1) - return 0; - } - } - return 0; + auto add_bonded = [&](Particle &p) { + int j = 0; + while (j < p.bl.n) { + auto type_num = p.bl.e[j++]; + auto iaparams = &bonded_ia_params[type_num]; + + /* fetch particle 2 */ + auto p2 = local_particles[p.bl.e[j++]]; + double dx[3]; + get_mi_vector(dx, p.r.p, p2->r.p); + std::array force; + calc_bonded_force(&p, p2, iaparams, &j, dx, force.data()); + PTENSOR_TRACE( + fprintf(stderr, "%d: Bonded to particle %d with force %f %f %f\n", + this_node, p2->p.identity, force[0], force[1], force[2])); + if ((pow(force[0], 2) + pow(force[1], 2) + pow(force[2], 2)) > 0) { + if (distribute_tensors(TensorInBin, force.data(), bins, range_start, + range, p.r.p.data(), p2->r.p.data()) != 1) + return 0; + } + } + return 0; }; - auto add_single_particle_contribution = [&add_ideal, &add_bonded](Particle &p) { + auto add_single_particle_contribution = [&add_ideal, + &add_bonded](Particle &p) { add_ideal(p); add_bonded(p); }; @@ -1012,73 +1248,82 @@ int local_stress_tensor_calc(DoubleList *TensorInBin, int bins[3], } /************************************************************/ -int observable_compute_stress_tensor(int v_comp, double *A) -{ +int observable_compute_stress_tensor(int v_comp, double *A) { int i, j; double value; double p_vel[3]; /* if desired (v_comp==1) replace ideal component with instantaneous one */ - if (total_pressure.init_status != 1+v_comp ) { + if (total_pressure.init_status != 1 + v_comp) { init_virials(&total_pressure); init_p_tensor(&total_p_tensor); init_virials_non_bonded(&total_pressure_non_bonded); init_p_tensor_non_bonded(&total_p_tensor_non_bonded); - if(v_comp && (integ_switch == INTEG_METHOD_NPT_ISO) && !(nptiso.invalidate_p_vel)) { + if (v_comp && (integ_switch == INTEG_METHOD_NPT_ISO) && + !(nptiso.invalidate_p_vel)) { if (total_pressure.init_status == 0) - master_pressure_calc(0); + master_pressure_calc(0); p_tensor.data.e[0] = 0.0; - MPI_Reduce(nptiso.p_vel, p_vel, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); - for(i=0; i<3; i++) - if(nptiso.geometry & nptiso.nptgeom_dir[i]) - p_tensor.data.e[0] += p_vel[i]; - p_tensor.data.e[0] /= (nptiso.dimension*nptiso.volume); - total_pressure.init_status = 1+v_comp; } - else + MPI_Reduce(nptiso.p_vel, p_vel, 3, MPI_DOUBLE, MPI_SUM, 0, + MPI_COMM_WORLD); + for (i = 0; i < 3; i++) + if (nptiso.geometry & nptiso.nptgeom_dir[i]) + p_tensor.data.e[0] += p_vel[i]; + p_tensor.data.e[0] /= (nptiso.dimension * nptiso.volume); + total_pressure.init_status = 1 + v_comp; + } else master_pressure_calc(v_comp); } - for(j=0; j<9; j++) { + for (j = 0; j < 9; j++) { value = total_p_tensor.data.e[j]; - for (i = 1; i < total_p_tensor.data.n/9; i++) value += total_p_tensor.data.e[9*i + j]; - A[j]=value; + for (i = 1; i < total_p_tensor.data.n / 9; i++) + value += total_p_tensor.data.e[9 * i + j]; + A[j] = value; } return 0; } -void update_stress_tensor (int v_comp) { - int i; - double p_vel[3]; - /* if desired (v_comp==1) replace ideal component with instantaneous one */ - if (total_pressure.init_status != 1+v_comp ) { - init_virials(&total_pressure); - init_p_tensor(&total_p_tensor); - - init_virials_non_bonded(&total_pressure_non_bonded); - init_p_tensor_non_bonded(&total_p_tensor_non_bonded); - - if(v_comp && (integ_switch == INTEG_METHOD_NPT_ISO) && !(nptiso.invalidate_p_vel)) { - if (total_pressure.init_status == 0) - master_pressure_calc(0); - p_tensor.data.e[0] = 0.0; - MPI_Reduce(nptiso.p_vel, p_vel, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); - for(i=0; i<3; i++) - if(nptiso.geometry & nptiso.nptgeom_dir[i]) - p_tensor.data.e[0] += p_vel[i]; - p_tensor.data.e[0] /= (nptiso.dimension*nptiso.volume); - total_pressure.init_status = 1+v_comp; } - else - master_pressure_calc(v_comp); - } +void update_stress_tensor(int v_comp) { + int i; + double p_vel[3]; + /* if desired (v_comp==1) replace ideal component with instantaneous one */ + if (total_pressure.init_status != 1 + v_comp) { + init_virials(&total_pressure); + init_p_tensor(&total_p_tensor); + + init_virials_non_bonded(&total_pressure_non_bonded); + init_p_tensor_non_bonded(&total_p_tensor_non_bonded); + + if (v_comp && (integ_switch == INTEG_METHOD_NPT_ISO) && + !(nptiso.invalidate_p_vel)) { + if (total_pressure.init_status == 0) + master_pressure_calc(0); + p_tensor.data.e[0] = 0.0; + MPI_Reduce(nptiso.p_vel, p_vel, 3, MPI_DOUBLE, MPI_SUM, 0, + MPI_COMM_WORLD); + for (i = 0; i < 3; i++) + if (nptiso.geometry & nptiso.nptgeom_dir[i]) + p_tensor.data.e[0] += p_vel[i]; + p_tensor.data.e[0] /= (nptiso.dimension * nptiso.volume); + total_pressure.init_status = 1 + v_comp; + } else + master_pressure_calc(v_comp); + } } -int analyze_local_stress_tensor(int* periodic, double* range_start, double* range, int* bins, DoubleList* TensorInBin) -{ - PTENSOR_TRACE(fprintf(stderr,"%d: Running analyze_local_stress_tensor\n",this_node)); +int analyze_local_stress_tensor(int *periodic, double *range_start, + double *range, int *bins, + DoubleList *TensorInBin) { + PTENSOR_TRACE( + fprintf(stderr, "%d: Running analyze_local_stress_tensor\n", this_node)); - mpi_local_stress_tensor(TensorInBin, bins, periodic,range_start, range); - PTENSOR_TRACE(fprintf(stderr,"%d: analyze_local_stress_tensor: finished mpi_local_stress_tensor \n",this_node)); + mpi_local_stress_tensor(TensorInBin, bins, periodic, range_start, range); + PTENSOR_TRACE(fprintf( + stderr, + "%d: analyze_local_stress_tensor: finished mpi_local_stress_tensor \n", + this_node)); - return ES_OK; + return ES_OK; } diff --git a/src/core/pressure.hpp b/src/core/pressure.hpp index c6352204a4..861296f048 100755 --- a/src/core/pressure.hpp +++ b/src/core/pressure.hpp @@ -33,7 +33,8 @@ /// extern Observable_stat virials, total_pressure, p_tensor, total_p_tensor; /// -extern Observable_stat_non_bonded virials_non_bonded, total_pressure_non_bonded, p_tensor_non_bonded, total_p_tensor_non_bonded; +extern Observable_stat_non_bonded virials_non_bonded, total_pressure_non_bonded, + p_tensor_non_bonded, total_p_tensor_non_bonded; /*@}*/ /** \name Exported Functions */ @@ -45,28 +46,36 @@ void init_p_tensor_non_bonded(Observable_stat_non_bonded *stat_nb); void init_p_tensor(Observable_stat *stat); void master_pressure_calc(int v_comp); - -/** Calculates the pressure in the system from a virial expansion using the terms from \ref calculate_verlet_virials or \ref nsq_calculate_virials dependeing on the used cell system.
+/** Calculates the pressure in the system from a virial expansion using the + terms from \ref calculate_verlet_virials or \ref nsq_calculate_virials + dependeing on the used cell system.
@param result here the data about the scalar pressure are stored @param result_t here the data about the stress tensor are stored - @param result_nb here the data about the intra- and inter- molecular nonbonded contributions to scalar pressure are stored - @param result_t_nb here the data about the intra- and inter- molecular nonbonded contributions to stress tensor are stored + @param result_nb here the data about the intra- and inter- molecular + nonbonded contributions to scalar pressure are stored + @param result_t_nb here the data about the intra- and inter- molecular + nonbonded contributions to stress tensor are stored @param v_comp flag which enables (1) compensation of the velocities required - for deriving a pressure reflecting \ref nptiso_struct::p_inst - (hence it only works with domain decomposition); naturally it - therefore doesn't make sense to use it without NpT. + for deriving a pressure reflecting \ref nptiso_struct::p_inst + (hence it only works with domain decomposition); naturally it + therefore doesn't make sense to use it without NpT. */ -void pressure_calc(double *result, double *result_t, double *result_nb, double *result_t_nb, int v_comp); +void pressure_calc(double *result, double *result_t, double *result_nb, + double *result_t_nb, int v_comp); /** implementation of 'analyse local_stress_tensor */ -int local_stress_tensor_calc (DoubleList *TensorInBin, int bins[3], int periodic[3], double range_start[3], double range[3]); +int local_stress_tensor_calc(DoubleList *TensorInBin, int bins[3], + int periodic[3], double range_start[3], + double range[3]); /** function to calculate stress tensor for the observables */ int observable_compute_stress_tensor(int v_comp, double *A); void update_pressure(int v_comp); void update_stress_tensor(int v_comp); -int analyze_local_stress_tensor(int* periodic, double* range_start, double* range, int* bins, DoubleList* local_stress_tensor); +int analyze_local_stress_tensor(int *periodic, double *range_start, + double *range, int *bins, + DoubleList *local_stress_tensor); /*@}*/ diff --git a/src/core/pressure_inline.hpp b/src/core/pressure_inline.hpp index 2414d59440..80294fc0c5 100644 --- a/src/core/pressure_inline.hpp +++ b/src/core/pressure_inline.hpp @@ -88,7 +88,12 @@ inline void add_non_bonded_pair_virials(Particle *p1, Particle *p2, double d[3], case COULOMB_P3M_GPU: case COULOMB_P3M: /** - Here we calculate the short ranged contribution of the electrostatics. These terms are called Pi_{dir, alpha, beta} in the paper by Essmann et al "A smooth particle mesh Ewald method", The Journal of Chemical Physics 103, 8577 (1995); doi: 10.1063/1.470117. The part Pi_{corr, alpha, beta} in the Essmann paper is not present here since M is the empty set in our simulations. + Here we calculate the short ranged contribution of the electrostatics. + These terms are called Pi_{dir, alpha, beta} in the paper by Essmann et al + "A smooth particle mesh Ewald method", The Journal of Chemical Physics + 103, 8577 (1995); doi: 10.1063/1.470117. The part Pi_{corr, alpha, beta} + in the Essmann paper is not present here since M is the empty set in our + simulations. */ force[0] = 0.0; force[1] = 0.0; @@ -169,8 +174,8 @@ inline void calc_bonded_force(Particle *p1, Particle *p2, calc_subt_lj_pair_force(p1, p2, iaparams, dx, force); break; #endif - /* since it is not clear at the moment how to handle a many body interaction - * here, I skip it */ + /* since it is not clear at the moment how to handle a many body interaction + * here, I skip it */ case BONDED_IA_ANGLE_HARMONIC: (*i)++; force[0] = force[1] = force[2] = 0; @@ -288,8 +293,8 @@ inline void calc_three_body_bonded_forces(Particle *p1, Particle *p2, #endif default: fprintf(stderr, "calc_three_body_bonded_forces: \ - WARNING: Bond type %d , atom %d unhandled, Atom 2: %d\n", iaparams->type, - p1->p.identity, p2->p.identity); + WARNING: Bond type %d , atom %d unhandled, Atom 2: %d\n", + iaparams->type, p1->p.identity, p2->p.identity); break; } } @@ -497,12 +502,17 @@ inline void add_kinetic_virials(Particle *p1, int v_comp) { /* kinetic energy */ { if (v_comp) - virials.data.e[0] += (Utils::sqr(p1->m.v[0] * time_step - p1->f.f[0] * 0.5 * time_step * time_step / p1->p.mass) + - Utils::sqr(p1->m.v[1] * time_step - p1->f.f[1] * 0.5 * time_step * time_step / p1->p.mass) + - Utils::sqr(p1->m.v[2] * time_step - p1->f.f[2] * 0.5 * time_step * time_step / p1->p.mass)) * - (*p1).p.mass; + virials.data.e[0] += + (Utils::sqr(p1->m.v[0] * time_step - + p1->f.f[0] * 0.5 * time_step * time_step / p1->p.mass) + + Utils::sqr(p1->m.v[1] * time_step - + p1->f.f[1] * 0.5 * time_step * time_step / p1->p.mass) + + Utils::sqr(p1->m.v[2] * time_step - + p1->f.f[2] * 0.5 * time_step * time_step / p1->p.mass)) * + (*p1).p.mass; else - virials.data.e[0] += (Utils::sqr(p1->m.v[0] * time_step) + Utils::sqr(p1->m.v[1] * time_step) + + virials.data.e[0] += (Utils::sqr(p1->m.v[0] * time_step) + + Utils::sqr(p1->m.v[1] * time_step) + Utils::sqr(p1->m.v[2] * time_step)) * (*p1).p.mass; } @@ -511,8 +521,8 @@ inline void add_kinetic_virials(Particle *p1, int v_comp) { * each will be done later) */ for (k = 0; k < 3; k++) for (l = 0; l < 3; l++) - p_tensor.data.e[k * 3 + l] += - (p1->m.v[k]*time_step) * (p1->m.v[l]*time_step) * (*p1).p.mass; + p_tensor.data.e[k * 3 + l] += + (p1->m.v[k] * time_step) * (p1->m.v[l] * time_step) * (*p1).p.mass; } #endif diff --git a/src/core/quartic.cpp b/src/core/quartic.cpp index 04c3134434..2dfcda21e8 100644 --- a/src/core/quartic.cpp +++ b/src/core/quartic.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file quartic.cpp * @@ -25,9 +25,9 @@ #include "quartic.hpp" #include "communication.hpp" -int quartic_set_params(int bond_type, double k0, double k1, double r,double r_cut) -{ - if(bond_type < 0) +int quartic_set_params(int bond_type, double k0, double k1, double r, + double r_cut) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -37,13 +37,13 @@ int quartic_set_params(int bond_type, double k0, double k1, double r,double r_cu bonded_ia_params[bond_type].p.quartic.r = r; bonded_ia_params[bond_type].p.quartic.r_cut = r_cut; bonded_ia_params[bond_type].type = BONDED_IA_QUARTIC; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; // printf("quartic k0 %e k1 %e r %e r_cut %e\n", // k0, k1, r, r_cut); /* broadcast interaction parameters */ - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); return ES_OK; } diff --git a/src/core/quartic.hpp b/src/core/quartic.hpp index 3132da3b7e..63b6da6d06 100644 --- a/src/core/quartic.hpp +++ b/src/core/quartic.hpp @@ -1,53 +1,56 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _QUARTIC_HPP #define _QUARTIC_HPP /** \file quartic.hpp - * Routines to calculate the HARMONIC Energy or/and HARMONIC force + * Routines to calculate the HARMONIC Energy or/and HARMONIC force * for a particle pair. * \ref forces.cpp */ /************************************************************/ -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" #include "random.hpp" +#include "utils.hpp" /// set the parameters for the quartic potential -int quartic_set_params(int bond_type, double k0, double k1, double r,double r_cut); +int quartic_set_params(int bond_type, double k0, double k1, double r, + double r_cut); /** Computes the QUARTIC pair force and adds this - force to the particle forces (see \ref interaction_data.cpp). + force to the particle forces (see \ref interaction_data.cpp). @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. - @param iaparams bond type number of the angle interaction (see \ref interaction_data.cpp). + @param iaparams bond type number of the angle interaction (see \ref + interaction_data.cpp). @param dx particle distance vector @param force returns force of particle 1 @return 0. */ -inline int calc_quartic_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force[3]) -{ +inline int calc_quartic_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, double dx[3], + double force[3]) { int i; double fac; double dist2 = sqrlen(dx); @@ -56,37 +59,48 @@ inline int calc_quartic_pair_force(Particle *p1, Particle *p2, Bonded_ia_paramet // printf("Quartic dist2 %e, dist %e\n", dist2, dist); - if ((iaparams->p.quartic.r_cut > 0.0) && - (dist > iaparams->p.quartic.r_cut)) + if ((iaparams->p.quartic.r_cut > 0.0) && (dist > iaparams->p.quartic.r_cut)) return 1; dr = dist - iaparams->p.quartic.r; - fac = (iaparams->p.quartic.k0 * dr + iaparams->p.quartic.k1 * dr * dr * dr)/dist; - - for(i=0;i<3;i++) - force[i] = -fac*dx[i]; + fac = (iaparams->p.quartic.k0 * dr + iaparams->p.quartic.k1 * dr * dr * dr) / + dist; - // printf("Quartic (%d-%d), dist %e, dx %e %e %e, dr %e, f %e %e %e\n", p1->p.identity, p2->p.identity, dist, dx[0], dx[1], dx[2], dr, force[0], force[1], force[2]); + for (i = 0; i < 3; i++) + force[i] = -fac * dx[i]; - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: QUARTIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist2,fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: QUARTIC f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist2,fac)); + // printf("Quartic (%d-%d), dist %e, dx %e %e %e, dr %e, f %e %e %e\n", + // p1->p.identity, p2->p.identity, dist, dx[0], dx[1], dx[2], dr, force[0], + // force[1], force[2]); + + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: QUARTIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, dist2, fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: QUARTIC f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, dist2, fac)); return 0; } -inline int quartic_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ +inline int quartic_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, double dx[3], + double *_energy) { double dist2 = sqrlen(dx); double dist = sqrt(dist2); - if ((iaparams->p.quartic.r_cut > 0.0) && - (dist > iaparams->p.quartic.r_cut)) + if ((iaparams->p.quartic.r_cut > 0.0) && (dist > iaparams->p.quartic.r_cut)) return 1; - + double dr2 = Utils::sqr(dist - iaparams->p.quartic.r); - *_energy = 0.5*iaparams->p.quartic.k0*dr2 + 0.25 * iaparams->p.quartic.k1 * Utils::sqr(dr2); + *_energy = 0.5 * iaparams->p.quartic.k0 * dr2 + + 0.25 * iaparams->p.quartic.k1 * Utils::sqr(dr2); return 0; } diff --git a/src/core/random.cpp b/src/core/random.cpp index 2b768eb2c2..8639c8dbb9 100755 --- a/src/core/random.cpp +++ b/src/core/random.cpp @@ -72,7 +72,8 @@ int get_state_size_of_generator() { /** Communication */ void mpi_random_seed_slave(int pnode, int cnt) { - int this_seed; user_has_seeded=true; + int this_seed; + user_has_seeded = true; MPI_Scatter(nullptr, 1, MPI_INT, &this_seed, 1, MPI_INT, 0, comm_cart); @@ -142,11 +143,13 @@ void init_random(void) { mpiCallbacks().add(mpi_random_get_stat_slave); } -void init_random_seed(int seed) -{ - std::seed_seq seeder{seed}; //come up with "sane" initialization to avoid too many zeros in the internal state of the Mersenne twister +void init_random_seed(int seed) { + std::seed_seq seeder{seed}; // come up with "sane" initialization to avoid too + // many zeros in the internal state of the + // Mersenne twister generator.seed(seeder); - generator.discard(1e6); //discard the first 1e6 random numbers to warm up the Mersenne-Twister PRNG + generator.discard(1e6); // discard the first 1e6 random numbers to warm up the + // Mersenne-Twister PRNG } } /* Random */ diff --git a/src/core/random.hpp b/src/core/random.hpp index 22a5bde95d..584148b019 100755 --- a/src/core/random.hpp +++ b/src/core/random.hpp @@ -30,9 +30,9 @@ #include "errorhandling.hpp" #include +#include #include #include -#include namespace Random { extern std::mt19937 generator; @@ -40,17 +40,17 @@ extern std::normal_distribution normal_distribution; extern std::uniform_real_distribution uniform_real_distribution; extern bool user_has_seeded; - /** * @brief checks the seeded state and throws error if unseeded * **/ -inline void check_user_has_seeded(){ +inline void check_user_has_seeded() { static bool unseeded_error_thrown = false; if (!user_has_seeded && !unseeded_error_thrown) { unseeded_error_thrown = true; - runtimeErrorMsg() <<"Please seed the random number generator.\nESPResSo can choose one for you with set_random_state_PRNG()."; - } + runtimeErrorMsg() << "Please seed the random number generator.\nESPResSo " + "can choose one for you with set_random_state_PRNG()."; + } return; } @@ -96,7 +96,8 @@ void init_random_seed(int seed); } /* Random */ /** - * @brief Draws a random real number from the uniform distribution in the range [0,1) + * @brief Draws a random real number from the uniform distribution in the range + * [0,1) */ inline double d_random() { @@ -106,45 +107,48 @@ inline double d_random() { } /** - * @brief draws a random integer from the uniform distribution in the range [0,maxint-1] + * @brief draws a random integer from the uniform distribution in the range + * [0,maxint-1] * * @param maxint range. */ -inline int i_random(int maxint){ +inline int i_random(int maxint) { using namespace Random; check_user_has_seeded(); - std::uniform_int_distribution uniform_int_dist(0, maxint-1); + std::uniform_int_distribution uniform_int_dist(0, maxint - 1); return uniform_int_dist(generator); } /** - * @brief draws a random number from the normal distribution with mean 0 and variance 1. + * @brief draws a random number from the normal distribution with mean 0 and + * variance 1. */ -inline double gaussian_random(void){ +inline double gaussian_random(void) { using namespace Random; check_user_has_seeded(); return normal_distribution(generator); } - /** * @brief Generator for cutoff Gaussian random numbers. * - * Generates a Gaussian random number and generates a number between -2 sigma and 2 sigma in the form of a Gaussian with standard deviation sigma=1.118591404 resulting in + * Generates a Gaussian random number and generates a number between -2 sigma + * and 2 sigma in the form of a Gaussian with standard deviation + * sigma=1.118591404 resulting in * an actual standard deviation of 1. * * @return Gaussian random number. */ -inline double gaussian_random_cut(void){ +inline double gaussian_random_cut(void) { using namespace Random; check_user_has_seeded(); - const double random_number=1.042267973*normal_distribution(generator); + const double random_number = 1.042267973 * normal_distribution(generator); - if ( fabs(random_number) > 2*1.042267973 ) { - if ( random_number > 0 ) { - return 2*1.042267973; + if (fabs(random_number) > 2 * 1.042267973) { + if (random_number > 0) { + return 2 * 1.042267973; } else { - return -2*1.042267973; + return -2 * 1.042267973; } } return random_number; diff --git a/src/core/rattle.cpp b/src/core/rattle.cpp index 3a792b7d2b..b1df1840ed 100755 --- a/src/core/rattle.cpp +++ b/src/core/rattle.cpp @@ -25,14 +25,14 @@ int n_rigidbonds = 0; #ifdef BOND_CONSTRAINT +#include "cells.hpp" +#include "communication.hpp" +#include "errorhandling.hpp" #include "global.hpp" +#include "grid.hpp" #include "integrate.hpp" -#include "particle_data.hpp" #include "interaction_data.hpp" -#include "errorhandling.hpp" -#include "communication.hpp" -#include "grid.hpp" -#include "cells.hpp" +#include "particle_data.hpp" #include #include diff --git a/src/core/rattle.hpp b/src/core/rattle.hpp index 89648d6200..2d0c440d84 100755 --- a/src/core/rattle.hpp +++ b/src/core/rattle.hpp @@ -1,28 +1,30 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef RATTLE_H #define RATTLE_H -/** \file rattle.hpp RATTLE Algorithm (Rattle: A "Velocity" Version of the Shake - * Algorithm for Molecular Dynamics Calculations, H.C Andersen, +/** \file rattle.hpp RATTLE Algorithm (Rattle: A "Velocity" Version of the + * Shake + * Algorithm for Molecular Dynamics Calculations, H.C + * Andersen, * J Comp Phys, 52, 24-34, 1983) * * For more information see \ref rattle.cpp "rattle.c". @@ -39,7 +41,8 @@ extern int n_rigidbonds; of the \ref Particle structure. Invoked from \ref correct_pos_shake() */ void save_old_pos(); -/** Propagate velocity and position while using SHAKE algorithm for bond constraint.*/ +/** Propagate velocity and position while using SHAKE algorithm for bond + * constraint.*/ void correct_pos_shake(); /** Correction of current velocities using RATTLE algorithm*/ diff --git a/src/core/reaction_ensemble.cpp b/src/core/reaction_ensemble.cpp index 8cd2fd7af8..3b13a5d9ff 100644 --- a/src/core/reaction_ensemble.cpp +++ b/src/core/reaction_ensemble.cpp @@ -188,7 +188,6 @@ void ReactionAlgorithm::check_reaction_ensemble() { #endif } - // boring helper functions /** * Automatically sets the volume which is used by the reaction ensemble to the @@ -465,8 +464,8 @@ bool ReactionAlgorithm::generic_oneway_reaction(int reaction_id) { p_ids_created_particles, hidden_particles_properties); double E_pot_new; - if(particle_inserted_too_close_to_another_one==true) - E_pot_new=std::numeric_limits::max(); + if (particle_inserted_too_close_to_another_one == true) + E_pot_new = std::numeric_limits::max(); else E_pot_new = calculate_current_potential_energy_of_system(); @@ -479,7 +478,8 @@ bool ReactionAlgorithm::generic_oneway_reaction(int reaction_id) { current_reaction, E_pot_old, E_pot_new, old_particle_numbers, old_state_index, new_state_index, only_make_configuration_changing_move); - std::vector exponential = {exp(-1.0 / temperature * (E_pot_new - E_pot_old))}; + std::vector exponential = { + exp(-1.0 / temperature * (E_pot_new - E_pot_old))}; current_reaction.accumulator_exponentials(exponential); if (d_random() < bf) { @@ -526,7 +526,6 @@ bool ReactionAlgorithm::generic_oneway_reaction(int reaction_id) { return reaction_is_accepted; } - /** * Calculates the change in particle numbers for the given reaction */ @@ -711,7 +710,6 @@ int ReactionAlgorithm::create_particle(int desired_type) { double charge = charges_of_types[desired_type]; #endif - pos_vec = get_random_position_in_box(); place_particle(p_id, pos_vec.data()); // set type @@ -730,15 +728,15 @@ int ReactionAlgorithm::create_particle(int desired_type) { // forces if (d_min < exclusion_radius) particle_inserted_too_close_to_another_one = true; // setting of a minimal - // distance is allowed to - // avoid overlapping - // configurations if there is - // a repulsive potential. - // States with very high - // energies have a probability - // of almost zero and - // therefore do not contribute - // to ensemble averages. + // distance is allowed to + // avoid overlapping + // configurations if there is + // a repulsive potential. + // States with very high + // energies have a probability + // of almost zero and + // therefore do not contribute + // to ensemble averages. return p_id; } @@ -772,7 +770,7 @@ bool ReactionAlgorithm::do_global_mc_move_for_particles_of_type( int type, int particle_number_of_type_to_be_changed, bool use_wang_landau) { m_tried_configurational_MC_moves += 1; bool got_accepted = false; - particle_inserted_too_close_to_another_one=false; + particle_inserted_too_close_to_another_one = false; int old_state_index = -1; if (use_wang_landau) { @@ -797,7 +795,7 @@ bool ReactionAlgorithm::do_global_mc_move_for_particles_of_type( // save old_position int p_id = get_random_p_id(type); - for (int i=0; i < particle_number_of_type_to_be_changed;i++) { + for (int i = 0; i < particle_number_of_type_to_be_changed; i++) { // determine a p_id you have not touched yet while (is_in_list(p_id, p_id_s_changed_particles)) { p_id = get_random_p_id( @@ -814,25 +812,26 @@ bool ReactionAlgorithm::do_global_mc_move_for_particles_of_type( // propose new positions std::vector new_pos(3); - for (int i=0; i < particle_number_of_type_to_be_changed; i++) { + for (int i = 0; i < particle_number_of_type_to_be_changed; i++) { p_id = p_id_s_changed_particles[i]; // change particle position new_pos = get_random_position_in_box(); // new_pos=get_random_position_in_box_enhanced_proposal_of_small_radii(); // //enhanced proposal of small radii place_particle(p_id, new_pos.data()); - double d_min = distto(partCfg(), new_pos.data(), p_id); // TODO also catch constraints with an IFDEF - // CONSTRAINTS here, but only interesting, - // when doing MD/ HMC because then the system - // might explode easily here due to high - - if(d_min::max(); + if (particle_inserted_too_close_to_another_one == true) + E_pot_new = std::numeric_limits::max(); else E_pot_new = calculate_current_potential_energy_of_system(); @@ -1670,10 +1669,10 @@ int WangLandauReactionEnsemble::load_wang_landau_checkpoint( } int ConstantpHEnsemble::get_random_valid_p_id() { - int random_p_id = i_random(max_seen_particle+1); - //draw random p_ids till we draw a pid which exists + int random_p_id = i_random(max_seen_particle + 1); + // draw random p_ids till we draw a pid which exists while (not particle_exists(random_p_id)) - random_p_id = i_random(max_seen_particle+1); + random_p_id = i_random(max_seen_particle + 1); return random_p_id; } @@ -1685,7 +1684,8 @@ int ConstantpHEnsemble::get_random_valid_p_id() { * Note that there is a difference in the usecase of the constant pH reactions * and the above reaction ensemble. For the constant pH simulation directily the * **apparent equilibrium constant which carries a unit** needs to be provided -- -* this is equivalent to the gamma of the reaction ensemble above, where the dimensionless +* this is equivalent to the gamma of the reaction ensemble above, where the +* dimensionless * reaction constant needs to be provided. Again: For the constant-pH algorithm * not the dimensionless reaction constant needs to be provided here, but the * apparent reaction constant. @@ -1751,15 +1751,18 @@ double ConstantpHEnsemble::calculate_acceptance_probability( double ln_bf; double pKa; const double beta = 1.0 / temperature; - pKa = -current_reaction.nu_bar*log10(current_reaction.gamma); - ln_bf = (E_pot_new - E_pot_old) - current_reaction.nu_bar* 1.0 / beta * log(10) * (m_constant_pH - pKa); + pKa = -current_reaction.nu_bar * log10(current_reaction.gamma); + ln_bf = + (E_pot_new - E_pot_old) - + current_reaction.nu_bar * 1.0 / beta * log(10) * (m_constant_pH - pKa); double bf = exp(-beta * ln_bf); return bf; } -std::pair WidomInsertion::measure_excess_chemical_potential(int reaction_id) { +std::pair +WidomInsertion::measure_excess_chemical_potential(int reaction_id) { SingleReaction ¤t_reaction = reactions[reaction_id]; - particle_inserted_too_close_to_another_one=false; + particle_inserted_too_close_to_another_one = false; const double E_pot_old = calculate_current_potential_energy_of_system(); // make reaction attempt @@ -1772,10 +1775,10 @@ std::pair WidomInsertion::measure_excess_chemical_potential(int r make_reaction_attempt(current_reaction, changed_particles_properties, p_ids_created_particles, hidden_particles_properties); double E_pot_new; - if(particle_inserted_too_close_to_another_one==true) - E_pot_new=std::numeric_limits::max(); + if (particle_inserted_too_close_to_another_one == true) + E_pot_new = std::numeric_limits::max(); else - E_pot_new= calculate_current_potential_energy_of_system(); + E_pot_new = calculate_current_potential_energy_of_system(); // reverse reaction attempt // reverse reaction // 1) delete created product particles @@ -1786,10 +1789,19 @@ std::pair WidomInsertion::measure_excess_chemical_potential(int r restore_properties(hidden_particles_properties, number_of_saved_properties); // 2)restore previously changed reactant particles restore_properties(changed_particles_properties, number_of_saved_properties); - std::vector exponential = {exp(-1.0 / temperature * (E_pot_new - E_pot_old))}; + std::vector exponential = { + exp(-1.0 / temperature * (E_pot_new - E_pot_old))}; current_reaction.accumulator_exponentials(exponential); - std::pair result=std::make_pair(-temperature*log(current_reaction.accumulator_exponentials.get_mean()[0]),std::abs(-temperature/current_reaction.accumulator_exponentials.get_mean()[0]*current_reaction.accumulator_exponentials.get_std_error()[0])); //(excess chemical potential; error excess chemical potential, determined via error propagation) + std::pair result = std::make_pair( + -temperature * + log(current_reaction.accumulator_exponentials.get_mean()[0]), + std::abs(-temperature / + current_reaction.accumulator_exponentials.get_mean()[0] * + current_reaction.accumulator_exponentials + .get_std_error()[0])); //(excess chemical potential; error + //excess chemical potential, + //determined via error propagation) return result; } diff --git a/src/core/reaction_ensemble.hpp b/src/core/reaction_ensemble.hpp index 320103943d..2cc12c11fa 100644 --- a/src/core/reaction_ensemble.hpp +++ b/src/core/reaction_ensemble.hpp @@ -1,11 +1,11 @@ #ifndef REACTION_ENSEMBLE_H #define REACTION_ENSEMBLE_H -#include "utils.hpp" #include "energy.hpp" -#include -#include +#include "utils.hpp" #include "utils/Accumulator.hpp" +#include +#include namespace ReactionEnsemble { @@ -51,7 +51,7 @@ struct EnergyCollectiveVariable : public CollectiveVariable { struct DegreeOfAssociationCollectiveVariable : public CollectiveVariable { std::vector corresponding_acid_types; int associated_type; - virtual double determine_current_state() override{ + virtual double determine_current_state() override { return calculate_degree_of_association(); } @@ -63,11 +63,9 @@ struct DegreeOfAssociationCollectiveVariable : public CollectiveVariable { */ double calculate_degree_of_association() { int total_number_of_corresponding_acid = 0; - for (int i = 0; - i < corresponding_acid_types.size(); - ++i) { - int num_of_current_type=number_of_particles_with_type( - corresponding_acid_types[i]); + for (int i = 0; i < corresponding_acid_types.size(); ++i) { + int num_of_current_type = + number_of_particles_with_type(corresponding_acid_types[i]); total_number_of_corresponding_acid += num_of_current_type; } if (total_number_of_corresponding_acid == 0) { @@ -75,7 +73,7 @@ struct DegreeOfAssociationCollectiveVariable : public CollectiveVariable { "corresponding acid types? Total particle " "number of corresponding acid type is zero\n"); } - int num_of_associated_acid=number_of_particles_with_type(associated_type); + int num_of_associated_acid = number_of_particles_with_type(associated_type); double degree_of_association = static_cast(num_of_associated_acid) / total_number_of_corresponding_acid; // cast to double because otherwise @@ -117,17 +115,17 @@ class ReactionAlgorithm { void check_reaction_ensemble(); int delete_particle(int p_id); - void add_reaction(double gamma, - const std::vector & _reactant_types, - const std::vector & _reactant_coefficients, - const std::vector & _product_types, - const std::vector & _product_coefficients); + void add_reaction(double gamma, const std::vector &_reactant_types, + const std::vector &_reactant_coefficients, + const std::vector &_product_types, + const std::vector &_product_coefficients); bool do_global_mc_move_for_particles_of_type(int type, int particle_number_of_type, const bool use_wang_landau); - bool particle_inserted_too_close_to_another_one; + bool particle_inserted_too_close_to_another_one; + protected: std::vector m_empty_p_ids_smaller_than_max_seen_particle; bool generic_oneway_reaction(int reaction_id); @@ -136,7 +134,7 @@ class ReactionAlgorithm { on_reaction_rejection_directly_after_entry(int &old_state_index) {} virtual void on_attempted_reaction(int &new_state_index) {} virtual void on_end_reaction(int &accepted_state) {} - + virtual void on_mc_rejection_directly_after_entry(int &old_state_index){}; virtual void on_mc_accept(int &new_state_index){}; virtual void on_mc_reject(int &old_state_index){}; @@ -148,7 +146,8 @@ class ReactionAlgorithm { std::vector &p_ids_created_particles, std::vector &hidden_particles_properties); void restore_properties(std::vector &property_list, - const int number_of_saved_properties); + const int number_of_saved_properties); + private: std::map save_old_particle_numbers(int reaction_id); @@ -168,7 +167,6 @@ class ReactionAlgorithm { void append_particle_property_of_random_particle( int type, std::vector &list_of_particles); - virtual double calculate_acceptance_probability( SingleReaction ¤t_reaction, double E_pot_old, double E_pot_new, std::map &old_particle_numbers, int old_state_index, @@ -183,7 +181,7 @@ class ReactionAlgorithm { }; ////////////////////////////////////////////////////////////////actual -///declaration of specific reaction algorithms +/// declaration of specific reaction algorithms class ReactionEnsemble : public ReactionAlgorithm { private: @@ -200,11 +198,11 @@ class WangLandauReactionEnsemble : public ReactionAlgorithm { bool do_not_sample_reaction_partition_function = false; double final_wang_landau_parameter = 0.00001; - void - add_new_CV_degree_of_association(int associated_type, double CV_minimum, - double CV_maximum, - const std::vector & _corresponding_acid_types); - void add_new_CV_potential_energy(const std::string & filename, double delta_CV); + void add_new_CV_degree_of_association( + int associated_type, double CV_minimum, double CV_maximum, + const std::vector &_corresponding_acid_types); + void add_new_CV_potential_energy(const std::string &filename, + double delta_CV); std::vector> collective_variables; std::string output_filename = ""; @@ -212,8 +210,10 @@ class WangLandauReactionEnsemble : public ReactionAlgorithm { std::vector min_boundaries_energies; std::vector max_boundaries_energies; - std::vector minimum_energies_at_flat_index; // only present in energy preparation run - std::vector maximum_energies_at_flat_index; // only present in energy preparation run + std::vector + minimum_energies_at_flat_index; // only present in energy preparation run + std::vector + maximum_energies_at_flat_index; // only present in energy preparation run int update_maximum_and_minimum_energies_at_current_state(); // use for // preliminary @@ -221,35 +221,35 @@ class WangLandauReactionEnsemble : public ReactionAlgorithm { // reweighting // runs int do_reaction(int reaction_steps) override; - void write_out_preliminary_energy_run_results(const std::string & filename); + void write_out_preliminary_energy_run_results(const std::string &filename); // checkpointing, only designed to reassign values of a previous simulation to // a new simulation with the same initialization process - int load_wang_landau_checkpoint(const std::string & identifier); - int write_wang_landau_checkpoint(const std::string & identifier); - void - write_wang_landau_results_to_file(const std::string & full_path_to_output_filename); - + int load_wang_landau_checkpoint(const std::string &identifier); + int write_wang_landau_checkpoint(const std::string &identifier); + void write_wang_landau_results_to_file( + const std::string &full_path_to_output_filename); private: void on_reaction_entry(int &old_state_index) override; - void on_reaction_rejection_directly_after_entry(int &old_state_index) override; + void + on_reaction_rejection_directly_after_entry(int &old_state_index) override; void on_attempted_reaction(int &new_state_index) override; void on_end_reaction(int &accepted_state) override; - double calculate_acceptance_probability(SingleReaction ¤t_reaction, - double E_pot_old, double E_pot_new, - std::map &old_particle_numbers, - int old_state_index, int new_state_index, - bool only_make_configuration_changing_move) override; + double calculate_acceptance_probability( + SingleReaction ¤t_reaction, double E_pot_old, double E_pot_new, + std::map &old_particle_numbers, int old_state_index, + int new_state_index, bool only_make_configuration_changing_move) override; void on_mc_rejection_directly_after_entry(int &old_state_index) override; void on_mc_accept(int &new_state_index) override; void on_mc_reject(int &old_state_index) override; int on_mc_use_WL_get_new_state() override; std::vector histogram; - std::vector wang_landau_potential; // equals the logarithm to basis e of the + std::vector + wang_landau_potential; // equals the logarithm to basis e of the // degeneracy of the states - + std::vector nr_subindices_of_collective_variable; double wang_landau_parameter = 1.0; // equals the logarithm to basis e of the // modification factor of the degeneracy of @@ -295,12 +295,11 @@ class WangLandauReactionEnsemble : public ReactionAlgorithm { double delta_CV); }; - - class ConstantpHEnsemble : public ReactionAlgorithm { public: double m_constant_pH = -10; int do_reaction(int reaction_steps) override; + private: double calculate_acceptance_probability( SingleReaction ¤t_reaction, double E_pot_old, double E_pot_new, @@ -312,14 +311,12 @@ class ConstantpHEnsemble : public ReactionAlgorithm { class WidomInsertion : public ReactionAlgorithm { public: - std::pair measure_excess_chemical_potential(int reaction_id); - + std::pair measure_excess_chemical_potential(int reaction_id); }; //////////////////////////////////////////////////////////////////free functions -double -calculate_factorial_expression(SingleReaction ¤t_reaction, - std::map& old_particle_numbers); +double calculate_factorial_expression(SingleReaction ¤t_reaction, + std::map &old_particle_numbers); double factorial_Ni0_divided_by_factorial_Ni0_plus_nu_i(int Ni0, int nu_i); } #endif diff --git a/src/core/reaction_field.cpp b/src/core/reaction_field.cpp index 5aadf10ae7..676d961098 100755 --- a/src/core/reaction_field.cpp +++ b/src/core/reaction_field.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file reaction_field.cpp * @@ -27,20 +27,23 @@ #ifdef ELECTROSTATICS #include "communication.hpp" -int rf_set_params(double kappa,double epsilon1,double epsilon2, double r_cut) -{ +int rf_set_params(double kappa, double epsilon1, double epsilon2, + double r_cut) { rf_params.kappa = kappa; rf_params.epsilon1 = epsilon1; rf_params.epsilon2 = epsilon2; rf_params.r_cut = r_cut; - rf_params.B =(2*(epsilon1-epsilon2)*(1+kappa*r_cut)-epsilon2*kappa*kappa*r_cut*r_cut)/((epsilon1+2*epsilon2)*(1+kappa*r_cut)+epsilon2*kappa*kappa*r_cut*r_cut); - if(rf_params.epsilon1 < 0.0) + rf_params.B = (2 * (epsilon1 - epsilon2) * (1 + kappa * r_cut) - + epsilon2 * kappa * kappa * r_cut * r_cut) / + ((epsilon1 + 2 * epsilon2) * (1 + kappa * r_cut) + + epsilon2 * kappa * kappa * r_cut * r_cut); + if (rf_params.epsilon1 < 0.0) return -1; - if(rf_params.epsilon2 < 0.0) + if (rf_params.epsilon2 < 0.0) return -1; - if(rf_params.r_cut < 0.0) + if (rf_params.r_cut < 0.0) return -2; mpi_bcast_coulomb_params(); @@ -50,11 +53,11 @@ int rf_set_params(double kappa,double epsilon1,double epsilon2, double r_cut) #ifdef INTER_RF -int interrf_set_params(int part_type_a, int part_type_b,int rf_on) -{ +int interrf_set_params(int part_type_a, int part_type_b, int rf_on) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; data->rf_on = rf_on; diff --git a/src/core/reaction_field.hpp b/src/core/reaction_field.hpp index a3c4e3985a..435fe08426 100755 --- a/src/core/reaction_field.hpp +++ b/src/core/reaction_field.hpp @@ -29,9 +29,9 @@ */ #include "debug.hpp" -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef ELECTROSTATICS @@ -99,7 +99,8 @@ inline void add_rf_coulomb_pair_force(Particle *p1, Particle *p2, double d[3], } } -inline double rf_coulomb_pair_energy_no_cutoff(const Particle *p1, const Particle *p2, +inline double rf_coulomb_pair_energy_no_cutoff(const Particle *p1, + const Particle *p2, double dist) { double fac; fac = 1.0 / dist - diff --git a/src/core/readpdb.cpp b/src/core/readpdb.cpp index 6a9fb515eb..25a32f614c 100644 --- a/src/core/readpdb.cpp +++ b/src/core/readpdb.cpp @@ -2,8 +2,8 @@ #include "grid.hpp" #include "lj.hpp" -#include #include +#include #include #ifdef READPDB_DEBUG @@ -14,53 +14,75 @@ #ifdef LENNARD_JONES /* Add user requested Lennard-Jones interactions */ -static void add_lj_interaction(std::set &types, std::vector interactions, const double rel_cutoff) { - for(std::vector::const_iterator it = interactions.begin(); it != interactions.end(); ++it) { - for(std::set::const_iterator jt = types.begin(); jt != types.end(); ++jt) { +static void add_lj_interaction( + std::set &types, + std::vector interactions, const double rel_cutoff) { + for (std::vector::const_iterator it = interactions.begin(); + it != interactions.end(); ++it) { + for (std::set::const_iterator jt = + types.begin(); + jt != types.end(); ++jt) { const double epsilon_ij = sqrt(it->epsilon * jt->epsilon); - const double sigma_ij = 0.5*(it->sigma+10.*jt->sigma); - const double cutoff_ij = rel_cutoff*sigma_ij; - const double shift_ij = -(pow(sigma_ij/cutoff_ij,12) - pow(sigma_ij/cutoff_ij,6)); - if((epsilon_ij <= 0) || (sigma_ij <= 0)) { - continue; - } - else { - READPDB_TRACE(printf("adding lj interaction types %d %d eps %e sig %e cut %e shift %e\n", - it->other_type, jt->espresso_id, epsilon_ij, sigma_ij, cutoff_ij, shift_ij);); - lennard_jones_set_params(it->other_type, jt->espresso_id, epsilon_ij, sigma_ij, - cutoff_ij, shift_ij, 0.0, 0.0); + const double sigma_ij = 0.5 * (it->sigma + 10. * jt->sigma); + const double cutoff_ij = rel_cutoff * sigma_ij; + const double shift_ij = + -(pow(sigma_ij / cutoff_ij, 12) - pow(sigma_ij / cutoff_ij, 6)); + if ((epsilon_ij <= 0) || (sigma_ij <= 0)) { + continue; + } else { + READPDB_TRACE(printf("adding lj interaction types %d %d eps %e sig %e " + "cut %e shift %e\n", + it->other_type, jt->espresso_id, epsilon_ij, + sigma_ij, cutoff_ij, shift_ij);); + lennard_jones_set_params(it->other_type, jt->espresso_id, epsilon_ij, + sigma_ij, cutoff_ij, shift_ij, 0.0, 0.0); } } } } /* Add Lennard-Jones interactions between particles added from pdb/itp file */ -static void add_lj_internal(std::set &types, const double rel_cutoff, bool only_diagonal) { - for(std::set::const_iterator it = types.begin(); it != types.end(); ++it) { - for(std::set::const_iterator jt = types.begin(); jt != types.end(); ++jt) { - if(it->espresso_id > jt->espresso_id) - continue; - if(only_diagonal && (it->espresso_id != jt->espresso_id)) - continue; +static void add_lj_internal( + std::set &types, + const double rel_cutoff, bool only_diagonal) { + for (std::set::const_iterator it = + types.begin(); + it != types.end(); ++it) { + for (std::set::const_iterator jt = + types.begin(); + jt != types.end(); ++jt) { + if (it->espresso_id > jt->espresso_id) + continue; + if (only_diagonal && (it->espresso_id != jt->espresso_id)) + continue; const double epsilon_ij = sqrtf(it->epsilon * jt->epsilon); - const double sigma_ij = 0.5*(10.*it->sigma+10.*jt->sigma); - const double cutoff_ij = rel_cutoff*sigma_ij; - const double shift_ij = -pow(sigma_ij/cutoff_ij,12) - pow(sigma_ij/cutoff_ij,6); - if((epsilon_ij <= 0) || (sigma_ij <= 0)) { - continue; - } - else { - READPDB_TRACE(printf("adding internal lj interaction types %d %d eps %e sig %e cut %e shift %e epsilon_i %e\n", - it->espresso_id, jt->espresso_id, epsilon_ij, sigma_ij, cutoff_ij, shift_ij, it->epsilon);); - lennard_jones_set_params(it->espresso_id, jt->espresso_id, epsilon_ij, sigma_ij, - cutoff_ij, shift_ij, 0.0, 0.0); + const double sigma_ij = 0.5 * (10. * it->sigma + 10. * jt->sigma); + const double cutoff_ij = rel_cutoff * sigma_ij; + const double shift_ij = + -pow(sigma_ij / cutoff_ij, 12) - pow(sigma_ij / cutoff_ij, 6); + if ((epsilon_ij <= 0) || (sigma_ij <= 0)) { + continue; + } else { + READPDB_TRACE(printf("adding internal lj interaction types %d %d eps " + "%e sig %e cut %e shift %e epsilon_i %e\n", + it->espresso_id, jt->espresso_id, epsilon_ij, + sigma_ij, cutoff_ij, shift_ij, it->epsilon);); + lennard_jones_set_params(it->espresso_id, jt->espresso_id, epsilon_ij, + sigma_ij, cutoff_ij, shift_ij, 0.0, 0.0); } } } } #endif /* LENNARD_JONES */ -static int add_particles(PdbParser::PdbParser &parser, int first_id, int default_type, std::set &seen_types, int first_type = 0, bool fit = false) { +static int add_particles(PdbParser::PdbParser &parser, int first_id, + int default_type, + std::set &seen_types, + int first_type = 0, bool fit = false) { double pos[3]; int id = first_id; int stat; @@ -70,60 +92,70 @@ static int add_particles(PdbParser::PdbParser &parser, int first_id, int default #endif PdbParser::BoundingBox bb; bb.llx = bb.lly = bb.llz = 0.0; - double bb_l[3] = { box_l[0], box_l[1], box_l[2] }; + double bb_l[3] = {box_l[0], box_l[1], box_l[2]}; bb = parser.calc_bounding_box(); - if(fit) { + if (fit) { bb_l[0] = (bb.urx - bb.llx); bb_l[1] = (bb.ury - bb.lly); bb_l[2] = (bb.urz - bb.llz); - READPDB_TRACE(printf("bb dimensions (%f %f %f)\n", bb_l[0], bb_l[1], bb_l[2])); + READPDB_TRACE( + printf("bb dimensions (%f %f %f)\n", bb_l[0], bb_l[1], bb_l[2])); READPDB_TRACE(printf("bb ll (%f %f %f)\n", bb.llx, bb.lly, bb.llz)); READPDB_TRACE(printf("bb ur (%f %f %f)\n", bb.urx, bb.ury, bb.urz)); - - for(int i = 0; i < 3; i++) { - if(bb_l[i] > box_l[i]) { - rescale_boxl(i, bb_l[i]); + + for (int i = 0; i < 3; i++) { + if (bb_l[i] > box_l[i]) { + rescale_boxl(i, bb_l[i]); } } } int last_type = first_type; - for(std::vector::const_iterator it = parser.pdb_atoms.begin(); it != parser.pdb_atoms.end(); ++it) { + for (std::vector::const_iterator it = + parser.pdb_atoms.begin(); + it != parser.pdb_atoms.end(); ++it) { pos[0] = (it->x - bb.llx); pos[1] = (it->y - bb.lly); pos[2] = (it->z - bb.llz); stat = place_particle(id, pos); - const std::map::const_iterator entry = parser.itp_atoms.find(it->i); - switch(stat) { + const std::map::const_iterator entry = + parser.itp_atoms.find(it->i); + switch (stat) { case ES_PART_OK: - std::cerr << "Warning: position and type of particle " << id << " was overwriten by value from pdb file." << std::endl; - /* Fall through */ + std::cerr << "Warning: position and type of particle " << id + << " was overwriten by value from pdb file." << std::endl; + /* Fall through */ case ES_PART_CREATED: - /* See if we have a type from itp file, otherwise set default type */ - if(entry != parser.itp_atoms.end()) { - PdbParser::itp_atomtype itp_atomtype = parser.itp_atomtypes[entry->second.type]; - /* See if we have seen that type before */ - std::set::iterator type_iterator = seen_types.find(itp_atomtype); - if(type_iterator == seen_types.end()) { - itp_atomtype.espresso_id=last_type++; - type_iterator = seen_types.insert(itp_atomtype).first; - } - itp_atomtype = *type_iterator; + /* See if we have a type from itp file, otherwise set default type */ + if (entry != parser.itp_atoms.end()) { + PdbParser::itp_atomtype itp_atomtype = + parser.itp_atomtypes[entry->second.type]; + /* See if we have seen that type before */ + std::set::iterator type_iterator = + seen_types.find(itp_atomtype); + if (type_iterator == seen_types.end()) { + itp_atomtype.espresso_id = last_type++; + type_iterator = seen_types.insert(itp_atomtype).first; + } + itp_atomtype = *type_iterator; #ifdef ELECTROSTATICS - q = entry->second.charge; + q = entry->second.charge; #endif - type = itp_atomtype.espresso_id; - READPDB_TRACE(printf("pdb-id %d es-id %d itp-type-id %d q %f es-type %d", it->i, id, itp_atomtype.id, q, itp_atomtype.espresso_id)); - READPDB_TRACE(std::cout << " res " << entry->second.type << std::endl); - } else { - type = default_type; + type = itp_atomtype.espresso_id; + READPDB_TRACE( + printf("pdb-id %d es-id %d itp-type-id %d q %f es-type %d", it->i, + id, itp_atomtype.id, q, itp_atomtype.espresso_id)); + READPDB_TRACE(std::cout << " res " << entry->second.type << std::endl); + } else { + type = default_type; #ifdef ELECTROSTATICS - q = 0; + q = 0; #endif } set_particle_type(id, type); @@ -141,45 +173,57 @@ static int add_particles(PdbParser::PdbParser &parser, int first_id, int default return id - first_id; } -int pdb_add_particles_from_file(char *pdb_file, int first_id, int type, std::vector &ljInteractions, double lj_rel_cutoff, - char *itp_file, int first_type, bool fit, bool lj_internal, bool lj_diagonal) { +int pdb_add_particles_from_file(char *pdb_file, int first_id, int type, + std::vector &ljInteractions, + double lj_rel_cutoff, char *itp_file, + int first_type, bool fit, bool lj_internal, + bool lj_diagonal) { int n_part; PdbParser::PdbParser parser; - if(!parser.parse_pdb_file(pdb_file)) + if (!parser.parse_pdb_file(pdb_file)) return 0; - if(itp_file) { - if(!parser.parse_itp_file(itp_file)) + if (itp_file) { + if (!parser.parse_itp_file(itp_file)) return 0; } #ifdef READPDB_DEBUG - for(std::map::const_iterator it = parser.itp_atoms.begin(); it != parser.itp_atoms.end(); ++it) { - printf("itp_atom id %d name '%s' q %e\n", it->second.i, it->second.type.c_str(), it->second.charge); + for (std::map::const_iterator it = + parser.itp_atoms.begin(); + it != parser.itp_atoms.end(); ++it) { + printf("itp_atom id %d name '%s' q %e\n", it->second.i, + it->second.type.c_str(), it->second.charge); } #endif /* Unique set of types that actually have particles */ std::set seen_types; - - n_part = add_particles(parser, first_id, type, seen_types, first_type,fit); + + n_part = add_particles(parser, first_id, type, seen_types, first_type, fit); #ifdef READPDB_DEBUG - for(std::map::const_iterator it = parser.itp_atomtypes.begin(); it != parser.itp_atomtypes.end(); ++it) { - printf("itp_atomtype id %d es_id %d name '%s' epsilon %e sigma %e\n", it->second.id, it->second.espresso_id, it->first.c_str(), it->second.epsilon, it->second.sigma); + for (std::map::const_iterator it = + parser.itp_atomtypes.begin(); + it != parser.itp_atomtypes.end(); ++it) { + printf("itp_atomtype id %d es_id %d name '%s' epsilon %e sigma %e\n", + it->second.id, it->second.espresso_id, it->first.c_str(), + it->second.epsilon, it->second.sigma); } - for(std::set::const_iterator it = seen_types.begin(); it != seen_types.end(); ++it) { - printf("atomtype %d espresso_type %d epsilon %e sigma %e\n", it->id, it->espresso_id, it->epsilon, it->sigma); + for (std::set::const_iterator it = + seen_types.begin(); + it != seen_types.end(); ++it) { + printf("atomtype %d espresso_type %d epsilon %e sigma %e\n", it->id, + it->espresso_id, it->epsilon, it->sigma); } #endif #ifdef LENNARD_JONES add_lj_interaction(seen_types, ljInteractions, lj_rel_cutoff); - if(lj_internal || lj_diagonal) + if (lj_internal || lj_diagonal) add_lj_internal(seen_types, lj_rel_cutoff, lj_diagonal); #endif return n_part; } - - diff --git a/src/core/readpdb.hpp b/src/core/readpdb.hpp index 22427f2f42..7ab6dfb5e7 100644 --- a/src/core/readpdb.hpp +++ b/src/core/readpdb.hpp @@ -1,20 +1,20 @@ /* Copyright (C) 2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* vim: set ts=8 sts=2 sw=2 et: */ @@ -26,7 +26,7 @@ struct PdbLJInteraction { int other_type; - double epsilon,sigma; + double epsilon, sigma; }; /** Call only on the master node: Parse pdb file and add contained particles. @@ -40,6 +40,10 @@ struct PdbLJInteraction { @return Number of particles that were added. */ -int pdb_add_particles_from_file(char *pdb_file, int first_id, int type, std::vector &ljInteractions, double lj_rel_cutoff=2.5, - char *itp_file=nullptr, int first_type=0, bool fit = false, bool lj_internal = false, bool lj_diagonal = false); +int pdb_add_particles_from_file(char *pdb_file, int first_id, int type, + std::vector &ljInteractions, + double lj_rel_cutoff = 2.5, + char *itp_file = nullptr, int first_type = 0, + bool fit = false, bool lj_internal = false, + bool lj_diagonal = false); #endif diff --git a/src/core/rotate_system.cpp b/src/core/rotate_system.cpp index ebca858d81..4145b37ab1 100644 --- a/src/core/rotate_system.cpp +++ b/src/core/rotate_system.cpp @@ -1,9 +1,9 @@ #include "cells.hpp" #include "communication.hpp" +#include "initialize.hpp" #include "particle_data.hpp" #include "rotation.hpp" #include "utils.hpp" -#include "initialize.hpp" #include diff --git a/src/core/rotation.cpp b/src/core/rotation.cpp index 623127575a..92eaf1ac7f 100755 --- a/src/core/rotation.cpp +++ b/src/core/rotation.cpp @@ -41,10 +41,10 @@ #include "initialize.hpp" #include "integrate.hpp" #include "interaction_data.hpp" +#include "lb.hpp" #include "particle_data.hpp" #include "thermostat.hpp" #include "utils.hpp" -#include "lb.hpp" #include #include @@ -72,7 +72,7 @@ static void define_Qdd(Particle *p, double Qd[4], double Qdd[4], double S[3], /** convert quaternions to the director */ /** Convert director to quaternions */ -int convert_quatu_to_quat(const Vector3d& d, Vector<4,double>& quat) { +int convert_quatu_to_quat(const Vector3d &d, Vector<4, double> &quat) { double d_xy, dm; double theta2, phi2; @@ -118,31 +118,30 @@ int convert_quatu_to_quat(const Vector3d& d, Vector<4,double>& quat) { the body-fixed frames. Taken from "Goldstein - Classical Mechanics" (Chapter 4.6 Eq. 4.47). */ -void define_rotation_matrix(Particle const &p, double A[9]) -{ - double q0q0 =p.r.quat[0]; - q0q0 *=q0q0; +void define_rotation_matrix(Particle const &p, double A[9]) { + double q0q0 = p.r.quat[0]; + q0q0 *= q0q0; - double q1q1 =p.r.quat[1]; - q1q1 *=q1q1; + double q1q1 = p.r.quat[1]; + q1q1 *= q1q1; - double q2q2 =p.r.quat[2]; - q2q2 *=q2q2; + double q2q2 = p.r.quat[2]; + q2q2 *= q2q2; - double q3q3 =p.r.quat[3]; - q3q3 *=q3q3; + double q3q3 = p.r.quat[3]; + q3q3 *= q3q3; - A[0 + 3*0] = q0q0 + q1q1 - q2q2 - q3q3; - A[1 + 3*1] = q0q0 - q1q1 + q2q2 - q3q3; - A[2 + 3*2] = q0q0 - q1q1 - q2q2 + q3q3; + A[0 + 3 * 0] = q0q0 + q1q1 - q2q2 - q3q3; + A[1 + 3 * 1] = q0q0 - q1q1 + q2q2 - q3q3; + A[2 + 3 * 2] = q0q0 - q1q1 - q2q2 + q3q3; - A[0 + 3*1] = 2*(p.r.quat[1]*p.r.quat[2] + p.r.quat[0]*p.r.quat[3]); - A[0 + 3*2] = 2*(p.r.quat[1]*p.r.quat[3] - p.r.quat[0]*p.r.quat[2]); - A[1 + 3*0] = 2*(p.r.quat[1]*p.r.quat[2] - p.r.quat[0]*p.r.quat[3]); + A[0 + 3 * 1] = 2 * (p.r.quat[1] * p.r.quat[2] + p.r.quat[0] * p.r.quat[3]); + A[0 + 3 * 2] = 2 * (p.r.quat[1] * p.r.quat[3] - p.r.quat[0] * p.r.quat[2]); + A[1 + 3 * 0] = 2 * (p.r.quat[1] * p.r.quat[2] - p.r.quat[0] * p.r.quat[3]); - A[1 + 3*2] = 2*(p.r.quat[2]*p.r.quat[3] + p.r.quat[0]*p.r.quat[1]); - A[2 + 3*0] = 2*(p.r.quat[1]*p.r.quat[3] + p.r.quat[0]*p.r.quat[2]); - A[2 + 3*1] = 2*(p.r.quat[2]*p.r.quat[3] - p.r.quat[0]*p.r.quat[1]); + A[1 + 3 * 2] = 2 * (p.r.quat[2] * p.r.quat[3] + p.r.quat[0] * p.r.quat[1]); + A[2 + 3 * 0] = 2 * (p.r.quat[1] * p.r.quat[3] + p.r.quat[0] * p.r.quat[2]); + A[2 + 3 * 1] = 2 * (p.r.quat[2] * p.r.quat[3] - p.r.quat[0] * p.r.quat[1]); } /** calculate the second derivative of the quaternion of a given particle @@ -150,7 +149,8 @@ void define_rotation_matrix(Particle const &p, double A[9]) void define_Qdd(Particle *p, double Qd[4], double Qdd[4], double S[3], double Wd[3]) { /* calculate the first derivative of the quaternion */ - /* Taken from "An improved algorithm for molecular dynamics simulation of rigid molecules", Sonnenschein, Roland (1985), Eq. 4.*/ + /* Taken from "An improved algorithm for molecular dynamics simulation of + * rigid molecules", Sonnenschein, Roland (1985), Eq. 4.*/ Qd[0] = 0.5 * (-p->r.quat[1] * p->m.omega[0] - p->r.quat[2] * p->m.omega[1] - p->r.quat[3] * p->m.omega[2]); @@ -164,24 +164,35 @@ void define_Qdd(Particle *p, double Qd[4], double Qdd[4], double S[3], p->r.quat[0] * p->m.omega[2]); /* Calculate the angular acceleration. */ - /* Taken from "An improved algorithm for molecular dynamics simulation of rigid molecules", Sonnenschein, Roland (1985), Eq. 5.*/ + /* Taken from "An improved algorithm for molecular dynamics simulation of + * rigid molecules", Sonnenschein, Roland (1985), Eq. 5.*/ if (p->p.rotation & ROTATION_X) - Wd[0] = (p->f.torque[0] + p->m.omega[1]*p->m.omega[2]*(p->p.rinertia[1]-p->p.rinertia[2]))/p->p.rinertia[0]; + Wd[0] = (p->f.torque[0] + + p->m.omega[1] * p->m.omega[2] * + (p->p.rinertia[1] - p->p.rinertia[2])) / + p->p.rinertia[0]; else Wd[0] = 0.0; if (p->p.rotation & ROTATION_Y) - Wd[1] = (p->f.torque[1] + p->m.omega[2]*p->m.omega[0]*(p->p.rinertia[2]-p->p.rinertia[0]))/p->p.rinertia[1]; + Wd[1] = (p->f.torque[1] + + p->m.omega[2] * p->m.omega[0] * + (p->p.rinertia[2] - p->p.rinertia[0])) / + p->p.rinertia[1]; else Wd[1] = 0.0; if (p->p.rotation & ROTATION_Z) - Wd[2] = (p->f.torque[2] + p->m.omega[0]*p->m.omega[1]*(p->p.rinertia[0]-p->p.rinertia[1]))/p->p.rinertia[2]; + Wd[2] = (p->f.torque[2] + + p->m.omega[0] * p->m.omega[1] * + (p->p.rinertia[0] - p->p.rinertia[1])) / + p->p.rinertia[2]; else Wd[2] = 0.0; auto const S1 = Qd[0] * Qd[0] + Qd[1] * Qd[1] + Qd[2] * Qd[2] + Qd[3] * Qd[3]; /* Calculate the second derivative of the quaternion. */ - /* Taken from "An improved algorithm for molecular dynamics simulation of rigid molecules", Sonnenschein, Roland (1985), Eq. 8.*/ + /* Taken from "An improved algorithm for molecular dynamics simulation of + * rigid molecules", Sonnenschein, Roland (1985), Eq. 8.*/ Qdd[0] = 0.5 * (-p->r.quat[1] * Wd[0] - p->r.quat[2] * Wd[1] - p->r.quat[3] * Wd[2]) - p->r.quat[0] * S1; @@ -214,15 +225,13 @@ void propagate_omega_quat_particle(Particle *p) { return; // Clear rotational velocity for blocked rotation axes. - if (! (p->p.rotation & ROTATION_X)) - p->m.omega[0]=0; - if (! (p->p.rotation & ROTATION_Y)) - p->m.omega[1]=0; - if (! (p->p.rotation & ROTATION_Z)) - p->m.omega[2]=0; - + if (!(p->p.rotation & ROTATION_X)) + p->m.omega[0] = 0; + if (!(p->p.rotation & ROTATION_Y)) + p->m.omega[1] = 0; + if (!(p->p.rotation & ROTATION_Z)) + p->m.omega[2] = 0; - define_Qdd(p, Qd, Qdd, S, Wd); /* Taken from "On the numerical integration of motion for rigid polyatomics: @@ -280,7 +289,7 @@ void convert_torques_propagate_omega() { // Skip particle if rotation is turned off entirely for it. if (!p.p.rotation) continue; - + double A[9]; define_rotation_matrix(p, A); @@ -317,7 +326,6 @@ void convert_torques_propagate_omega() { if (!(p.p.rotation & ROTATION_Z)) p.f.torque[2] = 0; - #if defined(ENGINE) && (defined(LB) || defined(LB_GPU)) double omega_swim[3] = {0, 0, 0}; double omega_swim_body[3] = {0, 0, 0}; @@ -447,7 +455,6 @@ void convert_initial_torques() { if (!(p.p.rotation & ROTATION_Z)) p.f.torque[2] = 0; - ONEPART_TRACE(if (p.p.identity == check_id) fprintf( stderr, "%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n", this_node, p.f.f[0], p.f.f[1], p.f.f[2], p.m.v[0], p.m.v[1], p.m.v[2])); @@ -468,36 +475,31 @@ void convert_omega_body_to_space(const Particle *p, double *omega) { A[2 + 3 * 2] * p->m.omega[2]; } -Vector3d convert_vector_body_to_space(const Particle& p, const Vector3d& vec) { - Vector3d res={0,0,0}; +Vector3d convert_vector_body_to_space(const Particle &p, const Vector3d &vec) { + Vector3d res = {0, 0, 0}; double A[9]; define_rotation_matrix(p, A); - res[0] = A[0 + 3 * 0] * vec[0] + A[1 + 3 * 0] * vec[1] + - A[2 + 3 * 0] * vec[2]; - res[1] = A[0 + 3 * 1] * vec[0] + A[1 + 3 * 1] * vec[1] + - A[2 + 3 * 1] * vec[2]; - res[2] = A[0 + 3 * 2] * vec[0] + A[1 + 3 * 2] * vec[1] + - A[2 + 3 * 2] * vec[2]; - + res[0] = + A[0 + 3 * 0] * vec[0] + A[1 + 3 * 0] * vec[1] + A[2 + 3 * 0] * vec[2]; + res[1] = + A[0 + 3 * 1] * vec[0] + A[1 + 3 * 1] * vec[1] + A[2 + 3 * 1] * vec[2]; + res[2] = + A[0 + 3 * 2] * vec[0] + A[1 + 3 * 2] * vec[1] + A[2 + 3 * 2] * vec[2]; + return res; } -Vector3d convert_vector_space_to_body(const Particle& p, const Vector3d& v) { - Vector3d res={0,0,0}; +Vector3d convert_vector_space_to_body(const Particle &p, const Vector3d &v) { + Vector3d res = {0, 0, 0}; double A[9]; define_rotation_matrix(p, A); - res[0] = A[0 + 3 * 0] * v[0] + A[0 + 3 * 1] * v[1] + - A[0 + 3 * 2] * v[2]; - res[1] = A[1 + 3 * 0] * v[0] + A[1 + 3 * 1] * v[1] + - A[1 + 3 * 2] * v[2]; - res[2] = A[2 + 3 * 0] * v[0] + A[2 + 3 * 1] * v[1] + - A[2 + 3 * 2] * v[2]; + res[0] = A[0 + 3 * 0] * v[0] + A[0 + 3 * 1] * v[1] + A[0 + 3 * 2] * v[2]; + res[1] = A[1 + 3 * 0] * v[0] + A[1 + 3 * 1] * v[1] + A[1 + 3 * 2] * v[2]; + res[2] = A[2 + 3 * 0] * v[0] + A[2 + 3 * 1] * v[1] + A[2 + 3 * 2] * v[2]; return res; } - - void convert_torques_body_to_space(const Particle *p, double *torque) { double A[9]; define_rotation_matrix(*p, A); @@ -531,7 +533,6 @@ void convert_vec_space_to_body(Particle *p, double *v, double *res) { res[2] = A[2 + 3 * 0] * v[0] + A[2 + 3 * 1] * v[1] + A[2 + 3 * 2] * v[2]; } - /** Rotate the particle p around the NORMALIZED axis aSpaceFrame by amount phi */ void local_rotate_particle(Particle *p, double *aSpaceFrame, double phi) { diff --git a/src/core/rotation.hpp b/src/core/rotation.hpp index e407dc954b..92948340e8 100755 --- a/src/core/rotation.hpp +++ b/src/core/rotation.hpp @@ -25,16 +25,15 @@ */ +#include "Vector.hpp" #include "gb.hpp" #include "particle_data.hpp" #include "thermostat.hpp" #include "utils.hpp" -#include "Vector.hpp" - -constexpr const int ROTATION_X =2; -constexpr const int ROTATION_Y =4; -constexpr const int ROTATION_Z =8; +constexpr const int ROTATION_X = 2; +constexpr const int ROTATION_Y = 4; +constexpr const int ROTATION_Z = 8; /************************************************************* * Functions * @@ -57,9 +56,8 @@ void convert_initial_torques(); void convert_omega_body_to_space(const Particle *p, double *omega); void convert_torques_body_to_space(const Particle *p, double *torque); - -Vector3d convert_vector_body_to_space(const Particle& p, const Vector3d& v); -Vector3d convert_vector_space_to_body(const Particle& p, const Vector3d& v); +Vector3d convert_vector_body_to_space(const Particle &p, const Vector3d &v); +Vector3d convert_vector_space_to_body(const Particle &p, const Vector3d &v); /** convert velocity form the lab-fixed coordinates to the body-fixed frame */ @@ -67,10 +65,11 @@ void convert_vel_space_to_body(const Particle *p, double *vel_body); /** Here we use quaternions to calculate the rotation matrix which will be used then to transform torques from the laboratory to - the body-fixed frames */ + the body-fixed frames */ void define_rotation_matrix(Particle const &p, double A[9]); -inline void convert_quat_to_quatu(const Vector<4,double>& quat, Vector3d& quatu) { +inline void convert_quat_to_quatu(const Vector<4, double> &quat, + Vector3d &quatu) { /* director */ quatu[0] = 2 * (quat[1] * quat[3] + quat[0] * quat[2]); quatu[1] = 2 * (quat[2] * quat[3] - quat[0] * quat[1]); @@ -78,24 +77,24 @@ inline void convert_quat_to_quatu(const Vector<4,double>& quat, Vector3d& quatu quat[3] * quat[3]); } -/** Multiply two quaternions */ +/** Multiply two quaternions */ template -void multiply_quaternions(const T1& a, const T2& b, T3& result) -{ - // Formula from http://www.j3d.org/matrix_faq/matrfaq_latest.html - result[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]; - result[1] = a[0] * b[1] + a[1] * b[0] + a[2] * b[3] - a[3] * b[2]; - result[2] = a[0] * b[2] + a[2] * b[0] + a[3] * b[1] - a[1] * b[3]; - result[3] = a[0] * b[3] + a[3] * b[0] + a[1] * b[2] - a[2] * b[1]; +void multiply_quaternions(const T1 &a, const T2 &b, T3 &result) { + // Formula from http://www.j3d.org/matrix_faq/matrfaq_latest.html + result[0] = a[0] * b[0] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3]; + result[1] = a[0] * b[1] + a[1] * b[0] + a[2] * b[3] - a[3] * b[2]; + result[2] = a[0] * b[2] + a[2] * b[0] + a[3] * b[1] - a[1] * b[3]; + result[3] = a[0] * b[3] + a[3] * b[0] + a[1] * b[2] - a[2] * b[1]; } /** Convert director to quaternions */ -int convert_quatu_to_quat(const Vector3d& d, Vector<4,double>& quat); +int convert_quatu_to_quat(const Vector3d &d, Vector<4, double> &quat); #ifdef DIPOLES /** convert a dipole moment to quaternions and dipolar strength */ -inline int convert_dip_to_quat(const Vector3d& dip, Vector<4,double>& quat, double *dipm) { +inline int convert_dip_to_quat(const Vector3d &dip, Vector<4, double> &quat, + double *dipm) { double dm; // Calculate magnitude of dipole moment dm = sqrt(dip[0] * dip[0] + dip[1] * dip[1] + dip[2] * dip[2]); @@ -106,7 +105,8 @@ inline int convert_dip_to_quat(const Vector3d& dip, Vector<4,double>& quat, do } /** convert quaternion director to the dipole moment */ -inline void convert_quatu_to_dip(const Vector3d& quatu, double dipm, Vector3d& dip) { +inline void convert_quatu_to_dip(const Vector3d &quatu, double dipm, + Vector3d &dip) { /* dipole moment */ dip[0] = quatu[0] * dipm; dip[1] = quatu[1] * dipm; diff --git a/src/core/scafacos.cpp b/src/core/scafacos.cpp index 6d721a5374..537fcdbd08 100644 --- a/src/core/scafacos.cpp +++ b/src/core/scafacos.cpp @@ -34,22 +34,21 @@ #include "cells.hpp" #include "communication.hpp" +#include "communication.hpp" #include "errorhandling.hpp" +#include "global.hpp" #include "grid.hpp" #include "initialize.hpp" #include "integrate.hpp" #include "interaction_data.hpp" #include "scafacos/Scafacos.hpp" #include "tuning.hpp" -#include "communication.hpp" -#include "global.hpp" -#include "utils.hpp" +#include "utils.hpp" /** This file contains the c-like interface for Scafacos */ namespace Scafacos { - /** Get available scafacos methods */ std::list available_methods() { return Scafacos::available_methods(); @@ -81,7 +80,7 @@ int ScafacosData::update_particle_data() { } for (auto const &p : local_cells.particles()) { - auto pos=folded_position(p); + auto pos = folded_position(p); positions.push_back(pos[0]); positions.push_back(pos[1]); positions.push_back(pos[2]); @@ -153,7 +152,7 @@ void ScafacosData::update_particle_forces() const { if (!dipolar()) { assert(it == fields.size()); } else { - int tmp=positions.size()/3; + int tmp = positions.size() / 3; assert(it == positions.size() / 3); } } @@ -180,19 +179,20 @@ double pair_energy(Particle *p1, Particle *p2, double dist) { return 0.; } - // Issues a runtime error if positions are outside the box domain // This is needed, because the scafacos grid sort produces an mpi deadlock // otherwise // Returns true if calculations can continue. -bool check_position_validity(const std::vector& pos) { - assert(pos.size()%3==0); - for (int i=0;ibox_l[j]) { - // Throwing exception rather than runtime error, because continuing will result +bool check_position_validity(const std::vector &pos) { + assert(pos.size() % 3 == 0); + for (int i = 0; i < pos.size() / 3; i++) { + for (int j = 0; j < 3; j++) { + if (pos[3 * i + j] < 0 || pos[3 * i + j] > box_l[j]) { + // Throwing exception rather than runtime error, because continuing will + // result // in mpi deadlock - throw std::runtime_error("Particle position outside the box domain not allowed for scafacos-based methods."); + throw std::runtime_error("Particle position outside the box domain not " + "allowed for scafacos-based methods."); return false; } } @@ -218,7 +218,8 @@ void add_long_range_force() { #endif } } else - throw std::runtime_error("Scafacos internal error. Instance pointer is not valid."); + throw std::runtime_error( + "Scafacos internal error. Instance pointer is not valid."); particles.update_particle_forces(); } @@ -235,8 +236,12 @@ double long_range_energy() { particles.potentials.begin(), 0.0); } else { #ifdef SCAFACOS_DIPOLES - scafacos->run_dipolar(particles.dipoles, particles.positions, particles.fields,particles.potentials); - return -0.5* coulomb.Dprefactor * std::inner_product(particles.dipoles.begin(),particles.dipoles.end(),particles.potentials.begin(),0.0); + scafacos->run_dipolar(particles.dipoles, particles.positions, + particles.fields, particles.potentials); + return -0.5 * coulomb.Dprefactor * + std::inner_product(particles.dipoles.begin(), + particles.dipoles.end(), + particles.potentials.begin(), 0.0); #endif } } @@ -255,15 +260,15 @@ void set_r_cut_and_tune_local(double r_cut) { /** Determine runtime for a specific cutoff */ double time_r_cut(double r_cut) { - assert(this_node==0); + assert(this_node == 0); double t; /** Set cutoff to time */ - mpi_call(mpi_scafacos_set_r_cut_and_tune_slave,0,0); + mpi_call(mpi_scafacos_set_r_cut_and_tune_slave, 0, 0); MPI_Bcast(&r_cut, 1, MPI_DOUBLE, 0, comm_cart); set_r_cut_and_tune_local(r_cut); - //mpi_bcast_coulomb_params(); + // mpi_bcast_coulomb_params(); return time_force_calc(10); } @@ -310,13 +315,11 @@ void tune() { /** Check whether we have to do a bisection for the short range cutoff */ /** Check if there is a user supplied cutoff */ if ((scafacos->has_near) && (scafacos->r_cut() <= 0.0)) { - // Tuning of r_cut needs to run on the master node because it relies on + // Tuning of r_cut needs to run on the master node because it relies on // master-slve mode communication - if (this_node==0) { + if (this_node == 0) { tune_r_cut(); - } - else - { + } else { return; // Tune on the master node will issue mpi calls } } else { @@ -325,44 +328,44 @@ void tune() { } } -static void set_params_safe(const std::string &method, const std::string ¶ms, bool dipolar_ia) { - if(scafacos) { +static void set_params_safe(const std::string &method, + const std::string ¶ms, bool dipolar_ia) { + if (scafacos) { delete scafacos; scafacos = 0; } scafacos = new Scafacos(method, comm_cart, params); - int per[3] = { PERIODIC(0) != 0, PERIODIC(1) != 0, PERIODIC(2) != 0 }; + int per[3] = {PERIODIC(0) != 0, PERIODIC(1) != 0, PERIODIC(2) != 0}; scafacos->set_dipolar(dipolar_ia); - #ifdef DIPOLES +#ifdef DIPOLES if (dipolar_ia) { coulomb.Dmethod = DIPOLAR_SCAFACOS; } - #endif - #ifdef ELECTROSTATICS +#endif +#ifdef ELECTROSTATICS if (!dipolar_ia) { coulomb.method = COULOMB_SCAFACOS; } - #endif +#endif scafacos->set_common_parameters(box_l, per, n_part); - + on_coulomb_change(); - + if (!dipolar_ia) { - tune(); + tune(); } } - /** Bend result from scafacos back to original format */ std::string get_method_and_parameters() { - if(!scafacos) { + if (!scafacos) { return std::string(); } - std::string p = scafacos->get_method()+" "+scafacos->get_parameters(); + std::string p = scafacos->get_method() + " " + scafacos->get_parameters(); std::replace(p.begin(), p.end(), ',', ' '); @@ -370,8 +373,9 @@ std::string get_method_and_parameters() { } double get_r_cut() { - if(scafacos) { - if (!scafacos->has_near) return 0; + if (scafacos) { + if (!scafacos->has_near) + return 0; return scafacos->r_cut(); } return 0.0; @@ -416,29 +420,28 @@ void set_dipolar(bool d) { void free_handle() { - if (this_node==0) - mpi_call(mpi_scafacos_free_slave, 0,0); - if(scafacos) { -delete scafacos; + if (this_node == 0) + mpi_call(mpi_scafacos_free_slave, 0, 0); + if (scafacos) { + delete scafacos; scafacos = 0; } } void update_system_params() { -// If scafacos is not active, do nothing -if (!scafacos) { -throw std::runtime_error("Scafacos object not there"); -} + // If scafacos is not active, do nothing + if (!scafacos) { + throw std::runtime_error("Scafacos object not there"); + } - int per[3] = { PERIODIC(0) != 0, PERIODIC(1) != 0, PERIODIC(2) != 0 }; + int per[3] = {PERIODIC(0) != 0, PERIODIC(1) != 0, PERIODIC(2) != 0}; int tmp; - MPI_Allreduce(&n_part,&tmp,1,MPI_INT,MPI_MAX,comm_cart); - n_part=tmp; + MPI_Allreduce(&n_part, &tmp, 1, MPI_INT, MPI_MAX, comm_cart); + n_part = tmp; scafacos->set_common_parameters(box_l, per, n_part); } - } // namespace scafacos #endif /* SCAFACOS */ @@ -463,19 +466,18 @@ void mpi_scafacos_set_parameters_slave(int n_method, int n_params) { #endif /* SCAFACOS */ } - void mpi_scafacos_free_slave(int a, int b) { - #if defined(SCAFACOS) +#if defined(SCAFACOS) using namespace Scafacos; free_handle(); - #endif +#endif } void mpi_scafacos_set_r_cut_and_tune_slave(int a, int b) { - #if defined(SCAFACOS) +#if defined(SCAFACOS) using namespace Scafacos; double r_cut; MPI_Bcast(&r_cut, 1, MPI_DOUBLE, 0, comm_cart); set_r_cut_and_tune_local(r_cut); - #endif +#endif } diff --git a/src/core/scafacos.hpp b/src/core/scafacos.hpp index 1dd0644145..20b4ef4d85 100644 --- a/src/core/scafacos.hpp +++ b/src/core/scafacos.hpp @@ -1,51 +1,53 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -/** \file This file contains the c-type wrapper interface to the (oop-) scafacos interface. */ +/** \file This file contains the c-type wrapper interface to the (oop-) scafacos + * interface. */ #ifndef __SCAFACOS_HPP #define __SCAFACOS_HPP #include "config.hpp" - #include #include #include "particle_data.hpp" namespace Scafacos { -#if defined(SCAFACOS) +#if defined(SCAFACOS) /** Near-field pair force */ -void add_pair_force(Particle *p1, Particle *p2, double *d, double dist, double *force); +void add_pair_force(Particle *p1, Particle *p2, double *d, double dist, + double *force); /** Near-field pair energy */ -double pair_energy(Particle* p1, Particle* p2, double dist); +double pair_energy(Particle *p1, Particle *p2, double dist); /** Long range part */ void add_long_range_force(); /** Calculate long range energy contribution */ -double long_range_energy(); +double long_range_energy(); /** Get parameters */ std::string get_method_and_parameters(); /** Set parameters */ -void set_parameters(const std::string &method, const std::string ¶ms, bool dipolar); +void set_parameters(const std::string &method, const std::string ¶ms, + bool dipolar); double get_r_cut(); /** Is scafacos used for dipolar interactions */ @@ -68,6 +70,6 @@ void free_handle(); /** Parameter callback */ void mpi_scafacos_set_parameters_slave(int n_method, int n_params); void mpi_scafacos_set_r_cut_and_tune_slave(int a, int b); -void mpi_scafacos_free_slave(int a, int b) ; +void mpi_scafacos_free_slave(int a, int b); #endif diff --git a/src/core/scafacos/Scafacos.cpp b/src/core/scafacos/Scafacos.cpp index 890d7abadb..6cf6e20975 100644 --- a/src/core/scafacos/Scafacos.cpp +++ b/src/core/scafacos/Scafacos.cpp @@ -1,26 +1,25 @@ #include "Scafacos.hpp" -#include "errorhandling.hpp" -#include #include "communication.hpp" +#include "errorhandling.hpp" #include "integrate.hpp" - +#include namespace Scafacos { -#define handle_error(stmt) { const FCSResult res = stmt; if(res) runtimeError(fcs_result_get_message(res)); } - -std::string Scafacos::get_parameters() { - return m_last_parameters; -} -std::string Scafacos::get_method() { - return method; -} +#define handle_error(stmt) \ + { \ + const FCSResult res = stmt; \ + if (res) \ + runtimeError(fcs_result_get_message(res)); \ + } +std::string Scafacos::get_parameters() { return m_last_parameters; } +std::string Scafacos::get_method() { return method; } std::list Scafacos::available_methods() { std::list methods; - + #ifdef FCS_ENABLE_DIRECT methods.push_back("direct"); #endif @@ -61,95 +60,100 @@ std::list Scafacos::available_methods() { return methods; } -Scafacos::Scafacos(const std::string &_method, MPI_Comm comm, const std::string ¶meters) : method(_method) { +Scafacos::Scafacos(const std::string &_method, MPI_Comm comm, + const std::string ¶meters) + : method(_method) { handle_error(fcs_init(&handle, method.c_str(), comm)); - + int near_flag; fcs_get_near_field_delegation(handle, &near_flag); has_near = near_flag != 0; fcs_set_resort(handle, 0); - - parse_parameters(parameters); + parse_parameters(parameters); } -Scafacos::~Scafacos() { - fcs_destroy(handle); -} +Scafacos::~Scafacos() { fcs_destroy(handle); } void Scafacos::parse_parameters(const std::string &s) { m_last_parameters = s; handle_error(fcs_parser(handle, s.c_str(), 0)); - } double Scafacos::r_cut() const { - if(has_near) { + if (has_near) { fcs_float r_cut; - - fcs_get_r_cut(handle, &r_cut); + + fcs_get_r_cut(handle, &r_cut); return r_cut; - } - else { + } else { return 0.0; } } - + void Scafacos::set_r_cut(double r_cut) { - if(has_near) { + if (has_near) { fcs_set_r_cut(handle, r_cut); } } void Scafacos::run(std::vector &charges, std::vector &positions, - std::vector &fields, std::vector &potentials) { + std::vector &fields, + std::vector &potentials) { const int local_n_part = charges.size(); - fields.resize(3*local_n_part); + fields.resize(3 * local_n_part); potentials.resize(local_n_part); handle_error(fcs_tune(handle, local_n_part, &(positions[0]), &(charges[0]))); - - handle_error(fcs_run(handle, local_n_part, &(positions[0]), &(charges[0]), &(fields[0]), &(potentials[0]))); + + handle_error(fcs_run(handle, local_n_part, &(positions[0]), &(charges[0]), + &(fields[0]), &(potentials[0]))); } #ifdef SCAFACOS_DIPOLES -void Scafacos::run_dipolar(std::vector &dipoles, std::vector &positions, - std::vector &fields, std::vector &potentials) { - assert(dipoles.size()%3==0); - const int local_n_part = dipoles.size()/3; - - fields.resize(6*local_n_part); - potentials.resize(3*local_n_part); - - - handle_error(fcs_set_dipole_particles(handle, local_n_part,&(positions[0]),&(dipoles[0]), &(fields[0]),&(potentials[0]))); +void Scafacos::run_dipolar(std::vector &dipoles, + std::vector &positions, + std::vector &fields, + std::vector &potentials) { + assert(dipoles.size() % 3 == 0); + const int local_n_part = dipoles.size() / 3; + + fields.resize(6 * local_n_part); + potentials.resize(3 * local_n_part); + + handle_error(fcs_set_dipole_particles(handle, local_n_part, &(positions[0]), + &(dipoles[0]), &(fields[0]), + &(potentials[0]))); handle_error(fcs_run(handle, 0, nullptr, nullptr, nullptr, nullptr)); } #endif -void Scafacos::tune(std::vector &charges, std::vector &positions) { - handle_error(fcs_tune(handle, charges.size(), &(positions[0]), &(charges[0]))); +void Scafacos::tune(std::vector &charges, + std::vector &positions) { + handle_error( + fcs_tune(handle, charges.size(), &(positions[0]), &(charges[0]))); } -void Scafacos::set_common_parameters(double *box_l, int *periodicity, int total_particles) { - double boxa[3] = { 0., 0., 0. }, boxb[3] = { 0., 0., 0. }, boxc[3] = { 0., 0., 0. }, off[3] = { 0., 0., 0. }; +void Scafacos::set_common_parameters(double *box_l, int *periodicity, + int total_particles) { + double boxa[3] = {0., 0., 0.}, boxb[3] = {0., 0., 0.}, boxc[3] = {0., 0., 0.}, + off[3] = {0., 0., 0.}; boxa[0] = box_l[0]; boxb[1] = box_l[1]; boxc[2] = box_l[2]; // Does scafacos calculate the near field part // For charges, if the method supports it, Es calculates near field - int sr=0; - if (! dipolar() && has_near ) { - sr=0; - } - else - { - // Scafacos does near field calc - sr=1; + int sr = 0; + if (!dipolar() && has_near) { + sr = 0; + } else { + // Scafacos does near field calc + sr = 1; } - handle_error(fcs_set_common(handle, sr, boxa, boxb, boxc, off, periodicity, total_particles)); + handle_error(fcs_set_common(handle, sr, boxa, boxb, boxc, off, periodicity, + total_particles)); #ifdef SCAFACOS_DIPOLES if (m_dipolar) handle_error(fcs_set_total_dipole_particles(handle, total_particles)); @@ -159,12 +163,10 @@ void Scafacos::set_common_parameters(double *box_l, int *periodicity, int total_ void Scafacos::set_dipolar(bool d) { #ifndef SCAFACOS_DIPOLES if (d) { - throw std::runtime_error("Dipolar extension not compiled in. Switch on via SCAFACOS_DIPOLES in myconfig.hpp"); + throw std::runtime_error("Dipolar extension not compiled in. Switch on via " + "SCAFACOS_DIPOLES in myconfig.hpp"); } #endif -m_dipolar =d; + m_dipolar = d; } - } - - diff --git a/src/core/scafacos/Scafacos.hpp b/src/core/scafacos/Scafacos.hpp index da20203c95..65ab72421c 100644 --- a/src/core/scafacos/Scafacos.hpp +++ b/src/core/scafacos/Scafacos.hpp @@ -1,18 +1,18 @@ -#include -#include -#include +#include "../config.hpp" #include +#include #include -#include "../config.hpp" - +#include +#include namespace Scafacos { /** \brief Abstraction of a method from the scafacos library */ struct Scafacos { - Scafacos(const std::string &_method, MPI_Comm comm, const std::string ¶meters); + Scafacos(const std::string &_method, MPI_Comm comm, + const std::string ¶meters); ~Scafacos(); /** Parse parameter string */ void parse_parameters(const std::string &s); @@ -22,10 +22,11 @@ struct Scafacos { std::string get_method(); /** Set parameters common to all methods */ - void set_common_parameters(double *box_l, int *periodicity, int total_particles); + void set_common_parameters(double *box_l, int *periodicity, + int total_particles); /** Calulate short range pair force if supported by the method */ - inline double pair_force(double dist) const { - if(has_near) { + inline double pair_force(double dist) const { + if (has_near) { fcs_float field; fcs_compute_near_field(handle, dist, &field); return field; @@ -35,8 +36,8 @@ struct Scafacos { } //* Get pair energy for near field contrib */ - inline double pair_energy(double dist) const { - if(has_near) { + inline double pair_energy(double dist) const { + if (has_near) { fcs_float potential; fcs_compute_near_potential(handle, dist, &potential); return potential; @@ -44,51 +45,44 @@ struct Scafacos { return 0.0; } - + /** Calculate the fields and potentials for charges */ void run(std::vector &charges, std::vector &positions, - std::vector &fields,std::vector &potentials); - - /** Calculate fields and potentials for dipoles */ - #ifdef SCAFACOS_DIPOLES + std::vector &fields, std::vector &potentials); + +/** Calculate fields and potentials for dipoles */ +#ifdef SCAFACOS_DIPOLES void run_dipolar(std::vector &dipoles, std::vector &positions, - std::vector &fields, std::vector &potentials); - - #endif + std::vector &fields, + std::vector &potentials); + +#endif /** Tune parameters */ void tune(std::vector &charges, std::vector &positions); /** Get shortrange cutoff (0.0 if not supported) */ double r_cut() const; /** Set cutoff */ - void set_r_cut(double r_cut); + void set_r_cut(double r_cut); /** Get a list of methods supported by the library */ static std::list available_methods(); - + /** Scafacos used for dipolar ia */ bool dipolar() { return m_dipolar; } /** Switch scafacos to dipolar ia */ void set_dipolar(bool d); - - - /** Handle from the library */ - FCS handle; - /** Whether the method supports near field delegation */ - bool has_near; - /** The scafacos method name of this instance */ - const std::string method; - /** The last parameters set */ - std::string m_last_parameters; - - /** Scafacos used for dipolar ia */ - bool m_dipolar; - + /** Handle from the library */ + FCS handle; + /** Whether the method supports near field delegation */ + bool has_near; + /** The scafacos method name of this instance */ + const std::string method; + /** The last parameters set */ + std::string m_last_parameters; + /** Scafacos used for dipolar ia */ + bool m_dipolar; }; - - } - - diff --git a/src/core/shapes/Cylinder.cpp b/src/core/shapes/Cylinder.cpp index d05acd29ba..c26ba8c40d 100644 --- a/src/core/shapes/Cylinder.cpp +++ b/src/core/shapes/Cylinder.cpp @@ -25,39 +25,39 @@ using namespace std; - namespace Shapes { std::pair Cylinder::dist_half_pore(double r, double z) const { assert(z >= 0.0); assert(r >= 0.0); - if (z >= m_half_length || r >= m_rad ) { - /* Outside */ - if (!m_open && z >= m_half_length && r < m_rad ) { - /* Closest feature: cap */ - return {0, -(z - m_half_length)}; - } else if ( z >= m_half_length && (m_open || r >= m_rad)) { - /* Closest feature: ring */ - return {-(r - m_rad), -(z - m_half_length)}; + if (z >= m_half_length || r >= m_rad) { + /* Outside */ + if (!m_open && z >= m_half_length && r < m_rad) { + /* Closest feature: cap */ + return {0, -(z - m_half_length)}; + } else if (z >= m_half_length && (m_open || r >= m_rad)) { + /* Closest feature: ring */ + return {-(r - m_rad), -(z - m_half_length)}; } else { - /* Closest feature: cylinder */ - return {-(r - m_rad), 0}; + /* Closest feature: cylinder */ + return {-(r - m_rad), 0}; } } else { /* Inside */ - if (!m_open && z >= m_half_length - m_rad && r < (z - (m_half_length - m_rad)) ) { - /* Closest feature: cap */ - return {0, m_half_length - z}; + if (!m_open && z >= m_half_length - m_rad && + r < (z - (m_half_length - m_rad))) { + /* Closest feature: cap */ + return {0, m_half_length - z}; } else { - /* Closest feature: cylinder */ - return {m_rad - r, 0}; + /* Closest feature: cylinder */ + return {m_rad - r, 0}; } } } int Cylinder::calculate_dist(const double *ppos, double *dist, - double *vec) const { + double *vec) const { /* Coordinate transform to cylinder coords with origin at m_center. */ Vector3d const c_dist = Vector3d(ppos, ppos + 3) - m_center; @@ -74,9 +74,9 @@ int Cylinder::calculate_dist(const double *ppos, double *dist, for the z > 0 case, and flip the result if appropriate. */ double dr, dz; std::tie(dr, dz) = dist_half_pore(r, std::abs(z)); - + double side = -1; - if (std::abs(z) >= m_half_length || r >= m_rad ) /* outside */ + if (std::abs(z) >= m_half_length || r >= m_rad) /* outside */ side = 1; if (z <= 0.0) { diff --git a/src/core/shapes/Cylinder.hpp b/src/core/shapes/Cylinder.hpp index 6c68d9307b..9fc0e93f21 100644 --- a/src/core/shapes/Cylinder.hpp +++ b/src/core/shapes/Cylinder.hpp @@ -71,8 +71,9 @@ class Cylinder : public Shape { public: Cylinder() : m_center({0.0, 0.0, 0.0}), m_axis({1.0, 0.0, 0.0}), m_rad(0), - m_length(0.0), m_open(false), m_direction(1.0) { precalc(); } - + m_length(0.0), m_open(false), m_direction(1.0) { + precalc(); + } double radius() const { return m_rad; } void set_radius(double const &radius) { @@ -98,7 +99,6 @@ class Cylinder : public Shape { int calculate_dist(const double *ppos, double *dist, double *vec) const override; - }; } #endif diff --git a/src/core/shapes/Ellipsoid.cpp b/src/core/shapes/Ellipsoid.cpp index 420f0a1373..687cd81e96 100644 --- a/src/core/shapes/Ellipsoid.cpp +++ b/src/core/shapes/Ellipsoid.cpp @@ -57,8 +57,9 @@ int Ellipsoid::calculate_dist(const double *ppos, double *dist, /* calculate dist and vec */ double distance = 0.; for (int i = 0; i < 3; i++) { - vec[i] = (ppos_e[i] - Utils::sqr(m_semiaxes[i]) * ppos_e[i] / - (l + Utils::sqr(m_semiaxes[i]))); + vec[i] = (ppos_e[i] - + Utils::sqr(m_semiaxes[i]) * ppos_e[i] / + (l + Utils::sqr(m_semiaxes[i]))); distance += Utils::sqr(vec[i]); } diff --git a/src/core/shapes/Ellipsoid.hpp b/src/core/shapes/Ellipsoid.hpp index bb6b892eae..e86fabb0d1 100644 --- a/src/core/shapes/Ellipsoid.hpp +++ b/src/core/shapes/Ellipsoid.hpp @@ -29,7 +29,8 @@ namespace Shapes { class Ellipsoid : public Shape { public: Ellipsoid() - : m_center({0.0, 0.0, 0.0}), m_semiaxes({1.0, 1.0, 1.0}), m_direction(1.0) { } + : m_center({0.0, 0.0, 0.0}), m_semiaxes({1.0, 1.0, 1.0}), + m_direction(1.0) {} int calculate_dist(const double *ppos, double *dist, double *vec) const override; diff --git a/src/core/shapes/Rhomboid.cpp b/src/core/shapes/Rhomboid.cpp index c1a8046a23..3aeb5491a9 100644 --- a/src/core/shapes/Rhomboid.cpp +++ b/src/core/shapes/Rhomboid.cpp @@ -26,7 +26,8 @@ using namespace std; namespace Shapes { -int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) const { +int Rhomboid::calculate_dist(const double *ppos, double *dist, + double *vec) const { double axb[3], bxc[3], axc[3]; double A, B, C; double a_dot_bxc, b_dot_axc, c_dot_axb; @@ -81,13 +82,16 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons // check for cone at pos+a - A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + + A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + (ppos[2] - m_pos[2] - m_a[2]) * bxc[2]; A /= a_dot_bxc; - B = (ppos[0] - m_pos[0] - m_a[0]) * axc[0] + (ppos[1] - m_pos[1] - m_a[1]) * axc[1] + + B = (ppos[0] - m_pos[0] - m_a[0]) * axc[0] + + (ppos[1] - m_pos[1] - m_a[1]) * axc[1] + (ppos[2] - m_pos[2] - m_a[2]) * axc[2]; B /= b_dot_axc; - C = (ppos[0] - m_pos[0] - m_a[0]) * axb[0] + (ppos[1] - m_pos[1] - m_a[1]) * axb[1] + + C = (ppos[0] - m_pos[0] - m_a[0]) * axb[0] + + (ppos[1] - m_pos[1] - m_a[1]) * axb[1] + (ppos[2] - m_pos[2] - m_a[2]) * axb[2]; C /= c_dot_axb; @@ -104,13 +108,16 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons // check for cone at pos+b - A = (ppos[0] - m_pos[0] - m_b[0]) * bxc[0] + (ppos[1] - m_pos[1] - m_b[1]) * bxc[1] + + A = (ppos[0] - m_pos[0] - m_b[0]) * bxc[0] + + (ppos[1] - m_pos[1] - m_b[1]) * bxc[1] + (ppos[2] - m_pos[2] - m_b[2]) * bxc[2]; A /= a_dot_bxc; - B = (ppos[0] - m_pos[0] - m_b[0]) * axc[0] + (ppos[1] - m_pos[1] - m_b[1]) * axc[1] + + B = (ppos[0] - m_pos[0] - m_b[0]) * axc[0] + + (ppos[1] - m_pos[1] - m_b[1]) * axc[1] + (ppos[2] - m_pos[2] - m_b[2]) * axc[2]; B /= b_dot_axc; - C = (ppos[0] - m_pos[0] - m_b[0]) * axb[0] + (ppos[1] - m_pos[1] - m_b[1]) * axb[1] + + C = (ppos[0] - m_pos[0] - m_b[0]) * axb[0] + + (ppos[1] - m_pos[1] - m_b[1]) * axb[1] + (ppos[2] - m_pos[2] - m_b[2]) * axb[2]; C /= c_dot_axb; @@ -127,13 +134,16 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons // check for cone at pos+c - A = (ppos[0] - m_pos[0] - m_c[0]) * bxc[0] + (ppos[1] - m_pos[1] - m_c[1]) * bxc[1] + + A = (ppos[0] - m_pos[0] - m_c[0]) * bxc[0] + + (ppos[1] - m_pos[1] - m_c[1]) * bxc[1] + (ppos[2] - m_pos[2] - m_c[2]) * bxc[2]; A /= a_dot_bxc; - B = (ppos[0] - m_pos[0] - m_c[0]) * axc[0] + (ppos[1] - m_pos[1] - m_c[1]) * axc[1] + + B = (ppos[0] - m_pos[0] - m_c[0]) * axc[0] + + (ppos[1] - m_pos[1] - m_c[1]) * axc[1] + (ppos[2] - m_pos[2] - m_c[2]) * axc[2]; B /= b_dot_axc; - C = (ppos[0] - m_pos[0] - m_c[0]) * axb[0] + (ppos[1] - m_pos[1] - m_c[1]) * axb[1] + + C = (ppos[0] - m_pos[0] - m_c[0]) * axb[0] + + (ppos[1] - m_pos[1] - m_c[1]) * axb[1] + (ppos[2] - m_pos[2] - m_c[2]) * axb[2]; C /= c_dot_axb; @@ -326,15 +336,18 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons // check for prism at edge m_pos+a, b - A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + + A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + (ppos[2] - m_pos[2] - m_a[2]) * bxc[2]; A /= a_dot_bxc; - C = (ppos[0] - m_pos[0] - m_a[0]) * axb[0] + (ppos[1] - m_pos[1] - m_a[1]) * axb[1] + + C = (ppos[0] - m_pos[0] - m_a[0]) * axb[0] + + (ppos[1] - m_pos[1] - m_a[1]) * axb[1] + (ppos[2] - m_pos[2] - m_a[2]) * axb[2]; C /= c_dot_axb; if (A >= 0 && C <= 0) { - tmp = (ppos[0] - m_pos[0] - m_a[0]) * m_b[0] + (ppos[1] - m_pos[1] - m_a[1]) * m_b[1] + + tmp = (ppos[0] - m_pos[0] - m_a[0]) * m_b[0] + + (ppos[1] - m_pos[1] - m_a[1]) * m_b[1] + (ppos[2] - m_pos[2] - m_a[2]) * m_b[2]; tmp /= m_b[0] * m_b[0] + m_b[1] * m_b[1] + m_b[2] * m_b[2]; @@ -350,15 +363,18 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons // check for prism at edge m_pos+a, c - A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + + A = (ppos[0] - m_pos[0] - m_a[0]) * bxc[0] + + (ppos[1] - m_pos[1] - m_a[1]) * bxc[1] + (ppos[2] - m_pos[2] - m_a[2]) * bxc[2]; A /= a_dot_bxc; - B = (ppos[0] - m_pos[0] - m_a[0]) * axc[0] + (ppos[1] - m_pos[1] - m_a[1]) * axc[1] + + B = (ppos[0] - m_pos[0] - m_a[0]) * axc[0] + + (ppos[1] - m_pos[1] - m_a[1]) * axc[1] + (ppos[2] - m_pos[2] - m_a[2]) * axc[2]; B /= b_dot_axc; if (A >= 0 && B <= 0) { - tmp = (ppos[0] - m_pos[0] - m_a[0]) * m_c[0] + (ppos[1] - m_pos[1] - m_a[1]) * m_c[1] + + tmp = (ppos[0] - m_pos[0] - m_a[0]) * m_c[0] + + (ppos[1] - m_pos[1] - m_a[1]) * m_c[1] + (ppos[2] - m_pos[2] - m_a[2]) * m_c[2]; tmp /= m_c[0] * m_c[0] + m_c[1] * m_c[1] + m_c[2] * m_c[2]; @@ -772,5 +788,4 @@ int Rhomboid::calculate_dist(const double *ppos, double *dist, double *vec) cons } return 0; } - } diff --git a/src/core/shapes/Sphere.cpp b/src/core/shapes/Sphere.cpp index b8b1de2807..32047a8a32 100644 --- a/src/core/shapes/Sphere.cpp +++ b/src/core/shapes/Sphere.cpp @@ -25,7 +25,6 @@ using namespace std; - namespace Shapes { int Sphere::calculate_dist(const double *ppos, double *dist, double *vec) const { diff --git a/src/core/shapes/SpheroCylinder.cpp b/src/core/shapes/SpheroCylinder.cpp index b93d0b2581..0ba93d4220 100644 --- a/src/core/shapes/SpheroCylinder.cpp +++ b/src/core/shapes/SpheroCylinder.cpp @@ -23,11 +23,10 @@ #include "utils.hpp" #include - namespace Shapes { int SpheroCylinder::calculate_dist(const double *ppos, double *dist, - double *vec) const { + double *vec) const { /* Coordinate transform to cylinder coords with origin at m_center. */ @@ -50,50 +49,51 @@ int SpheroCylinder::calculate_dist(const double *ppos, double *dist, double z_abs = std::abs(z); double side = 1; - if (r >= m_rad || (z_abs >= m_half_length && std::sqrt(r * r + std::pow(z_abs-m_half_length,2))) > m_rad ) { - /* Outside */ - if (z_abs >= m_half_length) { - /* Closest feature: hemisphere */ - double dir = 1; - if (z<0) - dir = -1; - Vector3d c_dist_cap = ppos_v - (m_center + dir * e_z * m_half_length); - *dist = c_dist_cap.norm() - m_rad; - c_dist_cap.normalize(); - Vector3d v = *dist * c_dist_cap; - for (int i = 0; i < 3; i++) { - vec[i] = v[i]; - } - *dist *= m_direction; - return 0; + if (r >= m_rad || + (z_abs >= m_half_length && + std::sqrt(r * r + std::pow(z_abs - m_half_length, 2))) > m_rad) { + /* Outside */ + if (z_abs >= m_half_length) { + /* Closest feature: hemisphere */ + double dir = 1; + if (z < 0) + dir = -1; + Vector3d c_dist_cap = ppos_v - (m_center + dir * e_z * m_half_length); + *dist = c_dist_cap.norm() - m_rad; + c_dist_cap.normalize(); + Vector3d v = *dist * c_dist_cap; + for (int i = 0; i < 3; i++) { + vec[i] = v[i]; + } + *dist *= m_direction; + return 0; } else { - /* Closest feature: cylinder */ - dr = -(r - m_rad); + /* Closest feature: cylinder */ + dr = -(r - m_rad); } } else { side = -1; /* Inside */ - if (z_abs <= m_half_length) { - /* Closest feature: cylinder */ - dr = m_rad - r; + if (z_abs <= m_half_length) { + /* Closest feature: cylinder */ + dr = m_rad - r; } else { - /* Closest feature: hemisphere */ - double dir = 1; - if (z<0) - dir = -1; - Vector3d c_dist_cap = -(ppos_v - (m_center + dir * e_z * m_half_length)); - *dist = m_rad - c_dist_cap.norm(); - c_dist_cap.normalize(); - Vector3d v = *dist * c_dist_cap; - for (int i = 0; i < 3; i++) { - vec[i] = v[i]; - } - *dist *= -m_direction; - return 0; - + /* Closest feature: hemisphere */ + double dir = 1; + if (z < 0) + dir = -1; + Vector3d c_dist_cap = -(ppos_v - (m_center + dir * e_z * m_half_length)); + *dist = m_rad - c_dist_cap.norm(); + c_dist_cap.normalize(); + Vector3d v = *dist * c_dist_cap; + for (int i = 0; i < 3; i++) { + vec[i] = v[i]; + } + *dist *= -m_direction; + return 0; } } - + *dist = std::sqrt(dr * dr) * m_direction * side; for (int i = 0; i < 3; i++) { vec[i] = -dr * e_r[i]; @@ -102,4 +102,3 @@ int SpheroCylinder::calculate_dist(const double *ppos, double *dist, return 0; } } - diff --git a/src/core/shapes/SpheroCylinder.hpp b/src/core/shapes/SpheroCylinder.hpp index 4111fabeb3..6c21a2eabb 100644 --- a/src/core/shapes/SpheroCylinder.hpp +++ b/src/core/shapes/SpheroCylinder.hpp @@ -25,7 +25,6 @@ #include "Shape.hpp" #include "Vector.hpp" - namespace Shapes { class SpheroCylinder : public Shape { public: @@ -65,12 +64,12 @@ class SpheroCylinder : public Shape { e_r_axis.normalize(); } - public: SpheroCylinder() : m_center({0.0, 0.0, 0.0}), m_axis({1.0, 0.0, 0.0}), m_rad(0), - m_length(0.0) { precalc(); } - + m_length(0.0) { + precalc(); + } double radius() const { return m_rad; } void set_radius(double const &radius) { @@ -95,7 +94,6 @@ class SpheroCylinder : public Shape { int calculate_dist(const double *ppos, double *dist, double *vec) const override; - }; } diff --git a/src/core/shapes/Stomatocyte.cpp b/src/core/shapes/Stomatocyte.cpp index 2e079af119..5c62b6a62c 100644 --- a/src/core/shapes/Stomatocyte.cpp +++ b/src/core/shapes/Stomatocyte.cpp @@ -91,12 +91,10 @@ int Stomatocyte::calculate_dist(const double *ppos, double *dist, (sqr(a) * d + 5 * sqr(c) * d + pow(d, 3) - sqr(a) * e - 5 * sqr(c) * e + 6 * c * d * e - 3 * sqr(d) * e - 6 * c * sqr(e) + 4 * d * sqr(e) - 2 * pow(e, 3) - - (3 * c + e) * - sqrt(-pow(a, 4) - - sqr(5 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + 2 * sqr(e)) + - 2 * sqr(a) * - (13 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + - 2 * sqr(e)))) / + (3 * c + e) * sqrt(-pow(a, 4) - sqr(5 * sqr(c) + sqr(d) + 6 * c * e - + 2 * d * e + 2 * sqr(e)) + + 2 * sqr(a) * (13 * sqr(c) + sqr(d) + 6 * c * e - + 2 * d * e + 2 * sqr(e)))) / (2 * a * (9 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + 2 * sqr(e)))); T1p = acos(-( @@ -105,23 +103,20 @@ int Stomatocyte::calculate_dist(const double *ppos, double *dist, sqr(a) * (3 * c + e) - d * sqrt(-pow(a, 4) - sqr(5 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + 2 * sqr(e)) + - 2 * sqr(a) * - (13 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + - 2 * sqr(e))) + + 2 * sqr(a) * (13 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + + 2 * sqr(e))) + e * sqrt(-pow(a, 4) - sqr(5 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + 2 * sqr(e)) + - 2 * sqr(a) * - (13 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + - 2 * sqr(e)))) / + 2 * sqr(a) * (13 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + + 2 * sqr(e)))) / (4 * c * (9 * sqr(c) + sqr(d) + 6 * c * e - 2 * d * e + 2 * sqr(e))))); T1 = 3.0 * M_PI / 4.0 - T1p; T2 = e; - T3sqrt = -sqr(b * c) * - (sqr(a) + 9 * sqr(c) + 4 * c * d + d * (2 * b + d) - - 2 * a * (b + 2 * c + d)) * + T3sqrt = -sqr(b * c) * (sqr(a) + 9 * sqr(c) + 4 * c * d + d * (2 * b + d) - + 2 * a * (b + 2 * c + d)) * (sqr(a) + 9 * sqr(c) + 4 * c * d + sqr(d) - 2 * a * (b + 2 * c + d) + 2 * b * (4 * c + d)); @@ -132,35 +127,31 @@ int Stomatocyte::calculate_dist(const double *ppos, double *dist, 3 * sqr(a) * b * (b + 2 * c + d) + sqr(b) * (25 * sqr(c) + 12 * c * d + 3 * sqr(d)) + b * (34 * pow(c, 3) + 25 * sqr(c) * d + 6 * c * sqr(d) + pow(d, 3)) - - a * b * - (2 * sqr(b) + 25 * sqr(c) + 12 * c * d + 3 * sqr(d) + - 6 * b * (2 * c + d)) + + a * b * (2 * sqr(b) + 25 * sqr(c) + 12 * c * d + 3 * sqr(d) + + 6 * b * (2 * c + d)) + 3 * sqrt(T3sqrt)) / - (4 * b * c * - (sqr(a) + sqr(b) + 13 * sqr(c) + 4 * c * d + sqr(d) + - 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d))))); + (4 * b * c * (sqr(a) + sqr(b) + 13 * sqr(c) + 4 * c * d + sqr(d) + + 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d))))); T3 = 3.0 * M_PI / 4.0 - T3p; - T4sqrt = -sqr(b) * sqr(c) * - (sqr(a) + 9 * sqr(c) + 4 * c * d + d * (2 * b + d) - - 2 * a * (b + 2 * c + d)) * + T4sqrt = -sqr(b) * sqr(c) * (sqr(a) + 9 * sqr(c) + 4 * c * d + + d * (2 * b + d) - 2 * a * (b + 2 * c + d)) * (sqr(a) + 9 * sqr(c) + 4 * c * d + sqr(d) - 2 * a * (b + 2 * c + d) + 2 * b * (4 * c + d)); T4sqrt = std::max(T4sqrt, 0.0); - T4 = acos((b * (-a + b + 2 * c + d) * - (sqr(a) + 2 * sqr(b) + 9 * sqr(c) + 4 * c * d + sqr(d) + - 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d)) - - 3 * sqrt(-sqr(b * c) * - (sqr(a) + 9 * sqr(c) + 4 * c * d + d * (2 * b + d) - - 2 * a * (b + 2 * c + d)) * - (sqr(a) + 9 * sqr(c) + 4 * c * d + sqr(d) - - 2 * a * (b + 2 * c + d) + 2 * b * (4 * c + d)))) / - (2 * sqr(b) * - (sqr(a) + sqr(b) + 13 * sqr(c) + 4 * c * d + sqr(d) + - 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d)))); + T4 = + acos((b * (-a + b + 2 * c + d) * + (sqr(a) + 2 * sqr(b) + 9 * sqr(c) + 4 * c * d + sqr(d) + + 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d)) - + 3 * sqrt(-sqr(b * c) * (sqr(a) + 9 * sqr(c) + 4 * c * d + + d * (2 * b + d) - 2 * a * (b + 2 * c + d)) * + (sqr(a) + 9 * sqr(c) + 4 * c * d + sqr(d) - + 2 * a * (b + 2 * c + d) + 2 * b * (4 * c + d)))) / + (2 * sqr(b) * (sqr(a) + sqr(b) + 13 * sqr(c) + 4 * c * d + sqr(d) + + 2 * b * (2 * c + d) - 2 * a * (b + 2 * c + d)))); // Radii for the various parts of the swimmer diff --git a/src/core/shapes/Stomatocyte.hpp b/src/core/shapes/Stomatocyte.hpp index a992b9334c..634f2b1652 100644 --- a/src/core/shapes/Stomatocyte.hpp +++ b/src/core/shapes/Stomatocyte.hpp @@ -28,27 +28,27 @@ namespace Shapes { class Stomatocyte : public Shape { public: - Stomatocyte() : m_position({0., 0., 0.}), m_orientation({1., 0., 0.}), - m_outer_radius(0.0), m_inner_radius(0.0), m_layer_width(0.0), - m_direction(0.0) {} + Stomatocyte() + : m_position({0., 0., 0.}), m_orientation({1., 0., 0.}), + m_outer_radius(0.0), m_inner_radius(0.0), m_layer_width(0.0), + m_direction(0.0) {} - int calculate_dist(const double *ppos, double *dist, double *vec) const override; + int calculate_dist(const double *ppos, double *dist, + double *vec) const override; Vector3d const &position() const { return m_position; } - void set_position(Vector3d const &position) { - m_position = position; - } + void set_position(Vector3d const &position) { m_position = position; } Vector3d const &orientation() const { return m_orientation; } void set_orientation(Vector3d const &orientation) { - m_orientation = orientation; + m_orientation = orientation; } - double &outer_radius() { return m_outer_radius; } - double &inner_radius() { return m_inner_radius; } - double &layer_width() { return m_layer_width; } - - double &direction() { return m_direction; } + double &outer_radius() { return m_outer_radius; } + double &inner_radius() { return m_inner_radius; } + double &layer_width() { return m_layer_width; } + + double &direction() { return m_direction; } private: /** Stomatocyte position. */ diff --git a/src/core/short_range_loop.hpp b/src/core/short_range_loop.hpp index aece64a1d2..0739b291a0 100644 --- a/src/core/short_range_loop.hpp +++ b/src/core/short_range_loop.hpp @@ -7,11 +7,11 @@ #include "algorithm/for_each_pair.hpp" #include "cells.hpp" +#include "collision.hpp" #include "grid.hpp" #include "integrate.hpp" #include "interaction_data.hpp" #include "utils/Batch.hpp" -#include "collision.hpp" /** * @brief Distance vector and length handed to pair kernels. @@ -101,11 +101,11 @@ void short_range_loop(ParticleKernel &&particle_kernel, first, last, /* Create a new functor that first runs the position copy and then the actual kernel. */ - make_batch( - [](Particle &p) { p.l.p_old=p.r.p; }, - std::forward(particle_kernel)), + make_batch([](Particle &p) { p.l.p_old = p.r.p; }, + std::forward(particle_kernel)), std::forward(pair_kernel), - VerletCriterion{skin, max_cut, coulomb_cutoff, dipolar_cutoff,collision_detection_cutoff()}); + VerletCriterion{skin, max_cut, coulomb_cutoff, dipolar_cutoff, + collision_detection_cutoff()}); /* Now everything is up-to-date */ rebuild_verletlist = 0; diff --git a/src/core/soft_sphere.cpp b/src/core/soft_sphere.cpp index 9f8e761760..3c62f7f094 100755 --- a/src/core/soft_sphere.cpp +++ b/src/core/soft_sphere.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file soft_sphere.cpp * @@ -29,18 +29,18 @@ #include "communication.hpp" -int soft_sphere_set_params(int part_type_a, int part_type_b, - double a, double n, double cut, double offset) -{ +int soft_sphere_set_params(int part_type_a, int part_type_b, double a, double n, + double cut, double offset) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - if (!data) return ES_ERROR; + if (!data) + return ES_ERROR; - data->soft_a = a; - data->soft_n = n; - data->soft_cut = cut; + data->soft_a = a; + data->soft_n = n; + data->soft_cut = cut; data->soft_offset = offset; - + /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); @@ -48,4 +48,3 @@ int soft_sphere_set_params(int part_type_a, int part_type_b, } #endif - diff --git a/src/core/soft_sphere.hpp b/src/core/soft_sphere.hpp index f03ac46c39..f510ae36dd 100755 --- a/src/core/soft_sphere.hpp +++ b/src/core/soft_sphere.hpp @@ -31,10 +31,10 @@ #ifdef SOFT_SPHERE -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" /// int soft_sphere_set_params(int part_type_a, int part_type_b, double a, double n, diff --git a/src/core/specfunc.cpp b/src/core/specfunc.cpp index a0bf7ce030..5800469386 100755 --- a/src/core/specfunc.cpp +++ b/src/core/specfunc.cpp @@ -1,46 +1,46 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file specfunc.cpp Special functions, see \ref specfunc.hpp "specfunc.h" */ -#include -#include "utils.hpp" #include "specfunc.hpp" #include "polynom.hpp" +#include "utils.hpp" +#include /* Original gsl header * specfunc/bessel_K0.cpp - * + * * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -55,79 +55,51 @@ /* based on SLATEC bk0(), bk0e() */ -/* chebyshev expansions +/* chebyshev expansions series for bk0 on the interval 0. to 4.00000d+00 - with weighted error 3.57e-19 - log weighted error 18.45 - significant figures required 17.99 - decimal places required 18.97 + with weighted error 3.57e-19 + log weighted error 18.45 + significant figures required 17.99 + decimal places required 18.97 series for ak0 on the interval 1.25000d-01 to 5.00000d-01 - with weighted error 5.34e-17 - log weighted error 16.27 - significant figures required 14.92 - decimal places required 16.89 + with weighted error 5.34e-17 + log weighted error 16.27 + significant figures required 14.92 + decimal places required 16.89 series for ak02 on the interval 0. to 1.25000d-01 - with weighted error 2.34e-17 - log weighted error 16.63 - significant figures required 14.67 - decimal places required 17.20 + with weighted error 2.34e-17 + log weighted error 16.63 + significant figures required 14.67 + decimal places required 17.20 */ static double bk0_data[11] = { - -.5 -0.03532739323390276872, - 0.3442898999246284869, - 0.03597993651536150163, - 0.00126461541144692592, - 0.00002286212103119451, - 0.00000025347910790261, - 0.00000000190451637722, - 0.00000000001034969525, - 0.00000000000004259816, - 0.00000000000000013744, - 0.00000000000000000035 -}; + -.5 - 0.03532739323390276872, 0.3442898999246284869, + 0.03597993651536150163, 0.00126461541144692592, + 0.00002286212103119451, 0.00000025347910790261, + 0.00000000190451637722, 0.00000000001034969525, + 0.00000000000004259816, 0.00000000000000013744, + 0.00000000000000000035}; static Polynom bk0_cs{bk0_data}; static double ak0_data[17] = { - 2.5 -0.07643947903327941, - -0.02235652605699819, - 0.00077341811546938, - -0.00004281006688886, - 0.00000308170017386, - -0.00000026393672220, - 0.00000002563713036, - -0.00000000274270554, - 0.00000000031694296, - -0.00000000003902353, - 0.00000000000506804, - -0.00000000000068895, - 0.00000000000009744, - -0.00000000000001427, - 0.00000000000000215, - -0.00000000000000033, - 0.00000000000000005 -}; + 2.5 - 0.07643947903327941, -0.02235652605699819, 0.00077341811546938, + -0.00004281006688886, 0.00000308170017386, -0.00000026393672220, + 0.00000002563713036, -0.00000000274270554, 0.00000000031694296, + -0.00000000003902353, 0.00000000000506804, -0.00000000000068895, + 0.00000000000009744, -0.00000000000001427, 0.00000000000000215, + -0.00000000000000033, 0.00000000000000005}; static Polynom ak0_cs{ak0_data}; static double ak02_data[14] = { - 2.5 -0.01201869826307592, - -0.00917485269102569, - 0.00014445509317750, - -0.00000401361417543, - 0.00000015678318108, - -0.00000000777011043, - 0.00000000046111825, - -0.00000000003158592, - 0.00000000000243501, - -0.00000000000020743, - 0.00000000000001925, - -0.00000000000000192, - 0.00000000000000020, - -0.00000000000000002 -}; + 2.5 - 0.01201869826307592, -0.00917485269102569, 0.00014445509317750, + -0.00000401361417543, 0.00000015678318108, -0.00000000777011043, + 0.00000000046111825, -0.00000000003158592, 0.00000000000243501, + -0.00000000000020743, 0.00000000000001925, -0.00000000000000192, + 0.00000000000000020, -0.00000000000000002}; static Polynom ak02_cs{ak02_data}; /* based on SLATEC besi0 */ @@ -135,168 +107,99 @@ static Polynom ak02_cs{ak02_data}; /* chebyshev expansions series for bi0 on the interval 0. to 9.00000d+00 - with weighted error 2.46e-18 - log weighted error 17.61 - significant figures required 17.90 - decimal places required 18.15 + with weighted error 2.46e-18 + log weighted error 17.61 + significant figures required 17.90 + decimal places required 18.15 series for ai0 on the interval 1.25000d-01 to 3.33333d-01 - with weighted error 7.87e-17 - log weighted error 16.10 - significant figures required 14.69 - decimal places required 16.76 + with weighted error 7.87e-17 + log weighted error 16.10 + significant figures required 14.69 + decimal places required 16.76 series for ai02 on the interval 0. to 1.25000d-01 - with weighted error 3.79e-17 - log weighted error 16.42 - significant figures required 14.86 - decimal places required 17.09 + with weighted error 3.79e-17 + log weighted error 16.42 + significant figures required 14.86 + decimal places required 17.09 */ static double bi0_data[12] = { - 5.5 -.07660547252839144951, - 1.92733795399380827000, - .22826445869203013390, - .01304891466707290428, - .00043442709008164874, - .00000942265768600193, - .00000014340062895106, - .00000000161384906966, - .00000000001396650044, - .00000000000009579451, - .00000000000000053339, - .00000000000000000245 -}; + 5.5 - .07660547252839144951, 1.92733795399380827000, .22826445869203013390, + .01304891466707290428, .00043442709008164874, .00000942265768600193, + .00000014340062895106, .00000000161384906966, .00000000001396650044, + .00000000000009579451, .00000000000000053339, .00000000000000000245}; static Polynom bi0_cs{bi0_data}; static double ai0_data[21] = { - .75 +.07575994494023796, - .00759138081082334, - .00041531313389237, - .00001070076463439, - -.00000790117997921, - -.00000078261435014, - .00000027838499429, - .00000000825247260, - -.00000001204463945, - .00000000155964859, - .00000000022925563, - -.00000000011916228, - .00000000001757854, - .00000000000112822, - -.00000000000114684, - .00000000000027155, - -.00000000000002415, - -.00000000000000608, - .00000000000000314, - -.00000000000000071, - .00000000000000007 -}; + .75 + .07575994494023796, .00759138081082334, .00041531313389237, + .00001070076463439, -.00000790117997921, -.00000078261435014, + .00000027838499429, .00000000825247260, -.00000001204463945, + .00000000155964859, .00000000022925563, -.00000000011916228, + .00000000001757854, .00000000000112822, -.00000000000114684, + .00000000000027155, -.00000000000002415, -.00000000000000608, + .00000000000000314, -.00000000000000071, .00000000000000007}; static Polynom ai0_cs{ai0_data}; static double ai02_data[22] = { - .75 +.05449041101410882, - .00336911647825569, - .00006889758346918, - .00000289137052082, - .00000020489185893, - .00000002266668991, - .00000000339623203, - .00000000049406022, - .00000000001188914, - -.00000000003149915, - -.00000000001321580, - -.00000000000179419, - .00000000000071801, - .00000000000038529, - .00000000000001539, - -.00000000000004151, - -.00000000000000954, - .00000000000000382, - .00000000000000176, - -.00000000000000034, - -.00000000000000027, - .00000000000000003 -}; + .75 + .05449041101410882, .00336911647825569, .00006889758346918, + .00000289137052082, .00000020489185893, .00000002266668991, + .00000000339623203, .00000000049406022, .00000000001188914, + -.00000000003149915, -.00000000001321580, -.00000000000179419, + .00000000000071801, .00000000000038529, .00000000000001539, + -.00000000000004151, -.00000000000000954, .00000000000000382, + .00000000000000176, -.00000000000000034, -.00000000000000027, + .00000000000000003}; static Polynom ai02_cs{ai02_data}; /* based on SLATEC besk1(), besk1e() */ -/* chebyshev expansions +/* chebyshev expansions series for bk1 on the interval 0. to 4.00000d+00 - with weighted error 7.02e-18 - log weighted error 17.15 - significant figures required 16.73 - decimal places required 17.67 + with weighted error 7.02e-18 + log weighted error 17.15 + significant figures required 16.73 + decimal places required 17.67 series for ak1 on the interval 1.25000d-01 to 5.00000d-01 - with weighted error 6.06e-17 - log weighted error 16.22 - significant figures required 15.41 - decimal places required 16.83 + with weighted error 6.06e-17 + log weighted error 16.22 + significant figures required 15.41 + decimal places required 16.83 series for ak12 on the interval 0. to 1.25000d-01 - with weighted error 2.58e-17 - log weighted error 16.59 - significant figures required 15.22 - decimal places required 17.16 + with weighted error 2.58e-17 + log weighted error 16.59 + significant figures required 15.22 + decimal places required 17.16 */ static double bk1_data[11] = { - 1.5 +0.0253002273389477705, - -0.3531559607765448760, - -0.1226111808226571480, - -0.0069757238596398643, - -0.0001730288957513052, - -0.0000024334061415659, - -0.0000000221338763073, - -0.0000000001411488392, - -0.0000000000006666901, - -0.0000000000000024274, - -0.0000000000000000070 -}; + 1.5 + 0.0253002273389477705, -0.3531559607765448760, -0.1226111808226571480, + -0.0069757238596398643, -0.0001730288957513052, -0.0000024334061415659, + -0.0000000221338763073, -0.0000000001411488392, -0.0000000000006666901, + -0.0000000000000024274, -0.0000000000000000070}; static Polynom bk1_cs{bk1_data}; static double ak1_data[17] = { - 2.5 +0.27443134069738830, - 0.07571989953199368, - -0.00144105155647540, - 0.00006650116955125, - -0.00000436998470952, - 0.00000035402774997, - -0.00000003311163779, - 0.00000000344597758, - -0.00000000038989323, - 0.00000000004720819, - -0.00000000000604783, - 0.00000000000081284, - -0.00000000000011386, - 0.00000000000001654, - -0.00000000000000248, - 0.00000000000000038, - -0.00000000000000006 -}; + 2.5 + 0.27443134069738830, 0.07571989953199368, -0.00144105155647540, + 0.00006650116955125, -0.00000436998470952, 0.00000035402774997, + -0.00000003311163779, 0.00000000344597758, -0.00000000038989323, + 0.00000000004720819, -0.00000000000604783, 0.00000000000081284, + -0.00000000000011386, 0.00000000000001654, -0.00000000000000248, + 0.00000000000000038, -0.00000000000000006}; static Polynom ak1_cs{ak1_data}; static double ak12_data[14] = { - 2.5 +0.06379308343739001, - 0.02832887813049721, - -0.00024753706739052, - 0.00000577197245160, - -0.00000020689392195, - 0.00000000973998344, - -0.00000000055853361, - 0.00000000003732996, - -0.00000000000282505, - 0.00000000000023720, - -0.00000000000002176, - 0.00000000000000215, - -0.00000000000000022, - 0.00000000000000002 -}; + 2.5 + 0.06379308343739001, 0.02832887813049721, -0.00024753706739052, + 0.00000577197245160, -0.00000020689392195, 0.00000000973998344, + -0.00000000055853361, 0.00000000003732996, -0.00000000000282505, + 0.00000000000023720, -0.00000000000002176, 0.00000000000000215, + -0.00000000000000022, 0.00000000000000002}; static Polynom ak12_cs{ak12_data}; /* based on SLATEC besi1(), besi1e() */ @@ -304,88 +207,50 @@ static Polynom ak12_cs{ak12_data}; /* chebyshev expansions series for bi1 on the interval 0. to 9.00000d+00 - with weighted error 2.40e-17 - log weighted error 16.62 - significant figures required 16.23 - decimal places required 17.14 + with weighted error 2.40e-17 + log weighted error 16.62 + significant figures required 16.23 + decimal places required 17.14 series for ai1 on the interval 1.25000d-01 to 3.33333d-01 - with weighted error 6.98e-17 - log weighted error 16.16 - significant figures required 14.53 - decimal places required 16.82 + with weighted error 6.98e-17 + log weighted error 16.16 + significant figures required 14.53 + decimal places required 16.82 series for ai12 on the interval 0. to 1.25000d-01 - with weighted error 3.55e-17 - log weighted error 16.45 - significant figures required 14.69 - decimal places required 17.12 + with weighted error 3.55e-17 + log weighted error 16.45 + significant figures required 14.69 + decimal places required 17.12 */ static double bi1_data[11] = { - 1.75 -0.001971713261099859, - 0.407348876675464810, - 0.034838994299959456, - 0.001545394556300123, - 0.000041888521098377, - 0.000000764902676483, - 0.000000010042493924, - 0.000000000099322077, - 0.000000000000766380, - 0.000000000000004741, - 0.000000000000000024 -}; + 1.75 - 0.001971713261099859, 0.407348876675464810, 0.034838994299959456, + 0.001545394556300123, 0.000041888521098377, 0.000000764902676483, + 0.000000010042493924, 0.000000000099322077, 0.000000000000766380, + 0.000000000000004741, 0.000000000000000024}; static Polynom bi1_cs{bi1_data}; static double ai1_data[21] = { - .75 -0.02846744181881479, - -0.01922953231443221, - -0.00061151858579437, - -0.00002069971253350, - 0.00000858561914581, - 0.00000104949824671, - -0.00000029183389184, - -0.00000001559378146, - 0.00000001318012367, - -0.00000000144842341, - -0.00000000029085122, - 0.00000000012663889, - -0.00000000001664947, - -0.00000000000166665, - 0.00000000000124260, - -0.00000000000027315, - 0.00000000000002023, - 0.00000000000000730, - -0.00000000000000333, - 0.00000000000000071, - -0.00000000000000006 -}; + .75 - 0.02846744181881479, -0.01922953231443221, -0.00061151858579437, + -0.00002069971253350, 0.00000858561914581, 0.00000104949824671, + -0.00000029183389184, -0.00000001559378146, 0.00000001318012367, + -0.00000000144842341, -0.00000000029085122, 0.00000000012663889, + -0.00000000001664947, -0.00000000000166665, 0.00000000000124260, + -0.00000000000027315, 0.00000000000002023, 0.00000000000000730, + -0.00000000000000333, 0.00000000000000071, -0.00000000000000006}; static Polynom ai1_cs{ai1_data}; static double ai12_data[22] = { - .75 +0.02857623501828014, - -0.00976109749136147, - -0.00011058893876263, - -0.00000388256480887, - -0.00000025122362377, - -0.00000002631468847, - -0.00000000383538039, - -0.00000000055897433, - -0.00000000001897495, - 0.00000000003252602, - 0.00000000001412580, - 0.00000000000203564, - -0.00000000000071985, - -0.00000000000040836, - -0.00000000000002101, - 0.00000000000004273, - 0.00000000000001041, - -0.00000000000000382, - -0.00000000000000186, - 0.00000000000000033, - 0.00000000000000028, - -0.00000000000000003 -}; + .75 + 0.02857623501828014, -0.00976109749136147, -0.00011058893876263, + -0.00000388256480887, -0.00000025122362377, -0.00000002631468847, + -0.00000000383538039, -0.00000000055897433, -0.00000000001897495, + 0.00000000003252602, 0.00000000001412580, 0.00000000000203564, + -0.00000000000071985, -0.00000000000040836, -0.00000000000002101, + 0.00000000000004273, 0.00000000000001041, -0.00000000000000382, + -0.00000000000000186, 0.00000000000000033, 0.00000000000000028, + -0.00000000000000003}; static Polynom ai12_cs{ai12_data}; /************************************************ @@ -396,147 +261,124 @@ static Polynom ai12_cs{ai12_data}; * B_{2j}/(2j)! */ static double hzeta_c[15] = { - 1.00000000000000000000000000000, - 0.083333333333333333333333333333, - -0.00138888888888888888888888888889, - 0.000033068783068783068783068783069, - -8.2671957671957671957671957672e-07, - 2.0876756987868098979210090321e-08, - -5.2841901386874931848476822022e-10, - 1.3382536530684678832826980975e-11, - -3.3896802963225828668301953912e-13, - 8.5860620562778445641359054504e-15, - -2.1748686985580618730415164239e-16, - 5.5090028283602295152026526089e-18, - -1.3954464685812523340707686264e-19, - 3.5347070396294674716932299778e-21, - -8.9535174270375468504026113181e-23 -}; + 1.00000000000000000000000000000, 0.083333333333333333333333333333, + -0.00138888888888888888888888888889, 0.000033068783068783068783068783069, + -8.2671957671957671957671957672e-07, 2.0876756987868098979210090321e-08, + -5.2841901386874931848476822022e-10, 1.3382536530684678832826980975e-11, + -3.3896802963225828668301953912e-13, 8.5860620562778445641359054504e-15, + -2.1748686985580618730415164239e-16, 5.5090028283602295152026526089e-18, + -1.3954464685812523340707686264e-19, 3.5347070396294674716932299778e-21, + -8.9535174270375468504026113181e-23}; /************************************************ * functions ************************************************/ -double hzeta(double s, double q) -{ +double hzeta(double s, double q) { double max_bits = 54.0; int jmax = 12, kmax = 10; int j, k; double pmax, scp, pcp, ans; - if((s > max_bits && q < 1.0) || (s > 0.5*max_bits && q < 0.25)) + if ((s > max_bits && q < 1.0) || (s > 0.5 * max_bits && q < 0.25)) return pow(q, -s); - if(s > 0.5*max_bits && q < 1.0) { + if (s > 0.5 * max_bits && q < 1.0) { double p1 = pow(q, -s); - double p2 = pow(q/(1.0+q), s); - double p3 = pow(q/(2.0+q), s); + double p2 = pow(q / (1.0 + q), s); + double p3 = pow(q / (2.0 + q), s); return p1 * (1.0 + p2 + p3); } - /* Euler-Maclaurin summation formula + /* Euler-Maclaurin summation formula * [Moshier, p. 400, with several typo corrections] */ - pmax = pow(kmax + q, -s); + pmax = pow(kmax + q, -s); scp = s; pcp = pmax / (kmax + q); - ans = pmax*((kmax+q)/(s-1.0) + 0.5); + ans = pmax * ((kmax + q) / (s - 1.0) + 0.5); - for(k=0; k= 27.) { - double tmp = .5*exp(-x)/sqrt(x); - return tmp*ak0_data[0]; + double tmp = .5 * exp(-x) / sqrt(x); + return tmp * ak0_data[0]; } if (x >= 23.) { - double tmp = exp(-x)/sqrt(x), xx = (16./3.)/x - 5./3.; - return tmp*(xx*ak0_data[1] + 0.5*ak0_data[0]); + double tmp = exp(-x) / sqrt(x), xx = (16. / 3.) / x - 5. / 3.; + return tmp * (xx * ak0_data[1] + 0.5 * ak0_data[0]); } if (x > 2) { int j = ak01_orders[((int)x) - 2]; @@ -545,60 +387,59 @@ double LPK0(double x) double *s0; if (x <= 8) { s0 = ak0_data; - x2 = (2.*16./3.)/x - 2.*5./3.; + x2 = (2. * 16. / 3.) / x - 2. * 5. / 3.; } else { s0 = ak02_data; - x2 = (2.*16.)/x - 2.; + x2 = (2. * 16.) / x - 2.; } dd0 = s0[j]; - d0 = x2*dd0 + s0[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + s0[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0; - d0 = x2*d0 - dd0 + s0[j]; + d0 = x2 * d0 - dd0 + s0[j]; dd0 = tmp0; } - tmp = exp(-x)/sqrt(x); - return tmp*(0.5*(s0[0] + x2*d0) - dd0); + tmp = exp(-x) / sqrt(x); + return tmp * (0.5 * (s0[0] + x2 * d0) - dd0); } /* x <= 2 */ { /* I0/1 series */ int j = 10; - double ret, tmp, x2 = (2./4.5)*x*x - 2.; + double ret, tmp, x2 = (2. / 4.5) * x * x - 2.; double dd0, d0; dd0 = bi0_data[j]; - d0 = x2*dd0 + bi0_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + bi0_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0; - d0 = x2*d0 - dd0 + bi0_data[j]; + d0 = x2 * d0 - dd0 + bi0_data[j]; dd0 = tmp0; } tmp = log(x) - M_LN2; - ret = -tmp*(0.5*(bi0_data[0] + x2*d0)- dd0); + ret = -tmp * (0.5 * (bi0_data[0] + x2 * d0) - dd0); /* K0/K1 correction */ j = 9; - x2 = x*x - 2.; + x2 = x * x - 2.; dd0 = bk0_data[j]; - d0 = x2*dd0 + bk0_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + bk0_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0; - d0 = x2*d0 - dd0 + bk0_data[j]; + d0 = x2 * d0 - dd0 + bk0_data[j]; dd0 = tmp0; } - return ret + (0.5*(x2*d0 + bk0_data[0]) - dd0); + return ret + (0.5 * (x2 * d0 + bk0_data[0]) - dd0); } } -double LPK1(double x) -{ +double LPK1(double x) { if (x >= 27.) { - double tmp = .5*exp(-x)/sqrt(x); - return tmp*ak1_data[0]; + double tmp = .5 * exp(-x) / sqrt(x); + return tmp * ak1_data[0]; } if (x >= 23.) { - double tmp = exp(-x)/sqrt(x), xx = (16./3.)/x - 5./3.; - return tmp*(xx*ak1_data[1] + 0.5*ak1_data[0]); + double tmp = exp(-x) / sqrt(x), xx = (16. / 3.) / x - 5. / 3.; + return tmp * (xx * ak1_data[1] + 0.5 * ak1_data[0]); } if (x > 2) { int j = ak01_orders[((int)x) - 2]; @@ -607,64 +448,63 @@ double LPK1(double x) double *s1; if (x <= 8) { s1 = ak1_data; - x2 = (2.*16./3.)/x - 2.*5./3.; + x2 = (2. * 16. / 3.) / x - 2. * 5. / 3.; } else { s1 = ak12_data; - x2 = (2.*16.)/x - 2.; + x2 = (2. * 16.) / x - 2.; } dd1 = s1[j]; - d1 = x2*dd1 + s1[j - 1]; - for(j -= 2; j >= 1; j--) { + d1 = x2 * dd1 + s1[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp1 = d1; - d1 = x2*d1 - dd1 + s1[j]; - dd1 = tmp1; + d1 = x2 * d1 - dd1 + s1[j]; + dd1 = tmp1; } - tmp = exp(-x)/sqrt(x); - return tmp*(0.5*(s1[0] + x2*d1) - dd1); + tmp = exp(-x) / sqrt(x); + return tmp * (0.5 * (s1[0] + x2 * d1) - dd1); } /* x <= 2 */ { /* I0/1 series */ int j = 10; - double ret, tmp, x2 = (2./4.5)*x*x - 2.; + double ret, tmp, x2 = (2. / 4.5) * x * x - 2.; double dd1, d1; dd1 = bi1_data[j]; - d1 = x2*dd1 + bi1_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d1 = x2 * dd1 + bi1_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp1 = d1; - d1 = x2*d1 - dd1 + bi1_data[j]; - dd1 = tmp1; + d1 = x2 * d1 - dd1 + bi1_data[j]; + dd1 = tmp1; } tmp = log(x) - M_LN2; - ret = x*tmp*(0.5*(bi1_data[0] + x2*d1) - dd1); + ret = x * tmp * (0.5 * (bi1_data[0] + x2 * d1) - dd1); /* K0/K1 correction */ j = 9; - x2 = x*x - 2.; + x2 = x * x - 2.; dd1 = bk1_data[j]; - d1 = x2*dd1 + bk1_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d1 = x2 * dd1 + bk1_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp1 = d1; - d1 = x2*d1 - dd1 + bk1_data[j]; - dd1 = tmp1; + d1 = x2 * d1 - dd1 + bk1_data[j]; + dd1 = tmp1; } - return ret + (0.5*(x2*d1 + bk1_data[0]) - dd1)/x; + return ret + (0.5 * (x2 * d1 + bk1_data[0]) - dd1) / x; } } -void LPK01(double x, double *K0, double *K1) -{ +void LPK01(double x, double *K0, double *K1) { if (x >= 27.) { - double tmp = .5*exp(-x)/sqrt(x); - *K0 = tmp*ak0_data[0]; - *K1 = tmp*ak1_data[0]; + double tmp = .5 * exp(-x) / sqrt(x); + *K0 = tmp * ak0_data[0]; + *K1 = tmp * ak1_data[0]; return; } if (x >= 23.) { - double tmp = exp(-x)/sqrt(x), xx = (16./3.)/x - 5./3.; - *K0 = tmp*(xx*ak0_data[1] + 0.5*ak0_data[0]); - *K1 = tmp*(xx*ak1_data[1] + 0.5*ak1_data[0]); - return; + double tmp = exp(-x) / sqrt(x), xx = (16. / 3.) / x - 5. / 3.; + *K0 = tmp * (xx * ak0_data[1] + 0.5 * ak0_data[0]); + *K1 = tmp * (xx * ak1_data[1] + 0.5 * ak1_data[0]); + return; } if (x > 2) { int j = ak01_orders[((int)x) - 2]; @@ -672,65 +512,67 @@ void LPK01(double x, double *K0, double *K1) double dd0, dd1, d0, d1; double *s0, *s1; if (x <= 8) { - s0 = ak0_data; s1 = ak1_data; - x2 = (2.*16./3.)/x - 2.*5./3.; + s0 = ak0_data; + s1 = ak1_data; + x2 = (2. * 16. / 3.) / x - 2. * 5. / 3.; } else { - s0 = ak02_data; s1 = ak12_data; - x2 = (2.*16.)/x - 2.; + s0 = ak02_data; + s1 = ak12_data; + x2 = (2. * 16.) / x - 2.; } dd0 = s0[j]; dd1 = s1[j]; - d0 = x2*dd0 + s0[j - 1]; - d1 = x2*dd1 + s1[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + s0[j - 1]; + d1 = x2 * dd1 + s1[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0, tmp1 = d1; - d0 = x2*d0 - dd0 + s0[j]; - d1 = x2*d1 - dd1 + s1[j]; + d0 = x2 * d0 - dd0 + s0[j]; + d1 = x2 * d1 - dd1 + s1[j]; dd0 = tmp0; - dd1 = tmp1; + dd1 = tmp1; } - tmp = exp(-x)/sqrt(x); - *K0 = tmp*(0.5*(s0[0] + x2*d0) - dd0); - *K1 = tmp*(0.5*(s1[0] + x2*d1) - dd1); + tmp = exp(-x) / sqrt(x); + *K0 = tmp * (0.5 * (s0[0] + x2 * d0) - dd0); + *K1 = tmp * (0.5 * (s1[0] + x2 * d1) - dd1); return; } /* x <= 2 */ { /* I0/1 series */ int j = 10; - double tmp, x2 = (2./4.5)*x*x - 2.; + double tmp, x2 = (2. / 4.5) * x * x - 2.; double dd0, dd1, d0, d1; dd0 = bi0_data[j]; dd1 = bi1_data[j]; - d0 = x2*dd0 + bi0_data[j - 1]; - d1 = x2*dd1 + bi1_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + bi0_data[j - 1]; + d1 = x2 * dd1 + bi1_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0, tmp1 = d1; - d0 = x2*d0 - dd0 + bi0_data[j]; - d1 = x2*d1 - dd1 + bi1_data[j]; + d0 = x2 * d0 - dd0 + bi0_data[j]; + d1 = x2 * d1 - dd1 + bi1_data[j]; dd0 = tmp0; - dd1 = tmp1; + dd1 = tmp1; } tmp = log(x) - M_LN2; - *K0 = -tmp*(0.5*(bi0_data[0] + x2*d0)- dd0); - *K1 = x*tmp*(0.5*(bi1_data[0] + x2*d1) - dd1); + *K0 = -tmp * (0.5 * (bi0_data[0] + x2 * d0) - dd0); + *K1 = x * tmp * (0.5 * (bi1_data[0] + x2 * d1) - dd1); /* K0/K1 correction */ j = 9; - x2 = x*x - 2.; + x2 = x * x - 2.; dd0 = bk0_data[j]; dd1 = bk1_data[j]; - d0 = x2*dd0 + bk0_data[j - 1]; - d1 = x2*dd1 + bk1_data[j - 1]; - for(j -= 2; j >= 1; j--) { + d0 = x2 * dd0 + bk0_data[j - 1]; + d1 = x2 * dd1 + bk1_data[j - 1]; + for (j -= 2; j >= 1; j--) { double tmp0 = d0, tmp1 = d1; - d0 = x2*d0 - dd0 + bk0_data[j]; - d1 = x2*d1 - dd1 + bk1_data[j]; + d0 = x2 * d0 - dd0 + bk0_data[j]; + d1 = x2 * d1 - dd1 + bk1_data[j]; dd0 = tmp0; - dd1 = tmp1; + dd1 = tmp1; } - *K0 += (0.5*(x2*d0 + bk0_data[0]) - dd0); - *K1 += (0.5*(x2*d1 + bk1_data[0]) - dd1)/x; + *K0 += (0.5 * (x2 * d0 + bk0_data[0]) - dd0); + *K1 += (0.5 * (x2 * d1 + bk1_data[0]) - dd1) / x; return; } } diff --git a/src/core/specfunc.hpp b/src/core/specfunc.hpp index 62c6657cb5..1c0afc09be 100755 --- a/src/core/specfunc.hpp +++ b/src/core/specfunc.hpp @@ -1,36 +1,46 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file specfunc.hpp - This file contains implementations for some special functions which are needed by the MMM family of - algorithms. This are the modified Hurwitz zeta function and the modified Bessel functions of first - and second kind. The implementations are based on the GSL code (see \ref specfunc.cpp "specfunc.c" + This file contains implementations for some special functions which are + needed by the MMM family of + algorithms. This are the modified Hurwitz zeta function and the modified + Bessel functions of first + and second kind. The implementations are based on the GSL code (see \ref + specfunc.cpp "specfunc.c" for the original GSL header). - The Hurwitz zeta function is evaluated using the Euler-MacLaurin summation formula, the Bessel functions - are evaluated using several different Chebychev expansions. Both achieve a precision of nearly machine - precision, which is no problem for the Hurwitz zeta function, which is only used when determining the - coefficients for the modified polygamma functions (see \ref mmm-common.hpp "mmm-common.h"). However, the - Bessel functions are actually used in the near formula of MMM2D, which is therefore slightly slower than - necessary. On the other hand, the number of terms in the Bessel sum is quite small normally, so that a less - precise version will probably not generate a huge computational speed improvement. + The Hurwitz zeta function is evaluated using the Euler-MacLaurin summation + formula, the Bessel functions + are evaluated using several different Chebychev expansions. Both achieve a + precision of nearly machine + precision, which is no problem for the Hurwitz zeta function, which is only + used when determining the + coefficients for the modified polygamma functions (see \ref mmm-common.hpp + "mmm-common.h"). However, the + Bessel functions are actually used in the near formula of MMM2D, which is + therefore slightly slower than + necessary. On the other hand, the number of terms in the Bessel sum is quite + small normally, so that a less + precise version will probably not generate a huge computational speed + improvement. */ #ifndef SPECFUNC_H #define SPECFUNC_H @@ -38,34 +48,41 @@ /** Hurwitz zeta function. This function was taken from the GSL code. */ double hzeta(double order, double x); -/** Modified Bessel function of first kind, order 0. This function was taken from +/** Modified Bessel function of first kind, order 0. This function was taken + from the GSL code. Precise roughly up to machine precision. */ double I0(double x); -/** Modified Bessel function of first kind, order 1. This function was taken from +/** Modified Bessel function of first kind, order 1. This function was taken + from the GSL code. Precise roughly up to machine precision. */ double I1(double x); -/** Modified Bessel function of second kind, order 0. This function was taken from +/** Modified Bessel function of second kind, order 0. This function was taken + from the GSL code. Precise roughly up to machine precision. */ double K0(double x); -/** Modified Bessel function of second kind, order 1. This function was taken from +/** Modified Bessel function of second kind, order 1. This function was taken + from the GSL code. Precise roughly up to machine precision. */ double K1(double x); /** Besselfunctions K0 at x. The implementation has an absolute precision of around 10^(-14), which is - comparable to the relative precision sqrt implementation of current hardware. + comparable to the relative precision sqrt implementation of current + hardware. */ double LPK0(double x); /** Besselfunctions K1 at x. The implementation has an absolute precision of around 10^(-14), which is - comparable to the relative precision sqrt implementation of current hardware. + comparable to the relative precision sqrt implementation of current + hardware. */ double LPK1(double x); /** Besselfunctions K0 and K1 at x. The implementation has an absolute precision of around 10^(-14), which is - comparable to the relative precision sqrt implementation of current hardware. + comparable to the relative precision sqrt implementation of current + hardware. */ void LPK01(double x, double *K0, double *K1); #endif diff --git a/src/core/statistics.cpp b/src/core/statistics.cpp index f077a219c7..25baa5d389 100755 --- a/src/core/statistics.cpp +++ b/src/core/statistics.cpp @@ -713,8 +713,8 @@ void density_profile_av(PartCfg &partCfg, int n_conf, int n_bin, double density, } int calc_cylindrical_average( - PartCfg &partCfg, std::vector const & center_, - std::vector const& direction_, double length, double radius, + PartCfg &partCfg, std::vector const ¢er_, + std::vector const &direction_, double length, double radius, int bins_axial, int bins_radial, std::vector types, std::map>>> &distribution) { @@ -1111,8 +1111,9 @@ void obsstat_realloc_and_clear(Observable_stat *stat, int n_pre, int n_bonded, int n_vs, int c_size) { // Number of doubles to store pressure in - const int total = c_size * (n_pre + bonded_ia_params.size() + n_non_bonded + n_coulomb + - n_dipolar + n_vs + Observable_stat::n_external_field); + const int total = + c_size * (n_pre + bonded_ia_params.size() + n_non_bonded + n_coulomb + + n_dipolar + n_vs + Observable_stat::n_external_field); // Allocate mem for the double list stat->data.resize(total); diff --git a/src/core/statistics.hpp b/src/core/statistics.hpp index 64fc56860d..ab8e000a1a 100755 --- a/src/core/statistics.hpp +++ b/src/core/statistics.hpp @@ -327,9 +327,9 @@ void density_profile_av(int n_conf, int n_bin, double density, int dir, double *rho_ave, int type); int calc_cylindrical_average( - PartCfg &, std::vector const& center, std::vector const& direction, - double length, double radius, int bins_axial, int bins_radial, - std::vector types, + PartCfg &, std::vector const ¢er, + std::vector const &direction, double length, double radius, + int bins_axial, int bins_radial, std::vector types, std::map>>> &distribution); diff --git a/src/core/statistics_chain.cpp b/src/core/statistics_chain.cpp index c94e724b3a..5215c9ca6f 100755 --- a/src/core/statistics_chain.cpp +++ b/src/core/statistics_chain.cpp @@ -21,11 +21,11 @@ /** \file statistics_chain.cpp Implementation of \ref statistics_chain.hpp "statistics_chain.hpp". */ +#include "statistics.hpp" +#include "PartCfg.hpp" #include "cells.hpp" #include "communication.hpp" #include "grid.hpp" -#include "PartCfg.hpp" -#include "statistics.hpp" #include "topology.hpp" #include "utils.hpp" @@ -44,12 +44,11 @@ int chain_length = 0; void update_mol_ids_setchains() { for (auto &p : local_cells.particles()) { - p.p.mol_id = - floor((p.p.identity - chain_start) / (double)chain_length); + p.p.mol_id = floor((p.p.identity - chain_start) / (double)chain_length); } } -void calc_re(PartCfg & partCfg, double **_re) { +void calc_re(PartCfg &partCfg, double **_re) { int i; double dx, dy, dz; double dist = 0.0, dist2 = 0.0, dist4 = 0.0; @@ -86,12 +85,14 @@ void calc_re_av(double **_re) { for (i = 0; i < chain_n_chains; i++) { dx = configs[j][3 * (chain_start + i * chain_length + chain_length - 1)] - configs[j][3 * (chain_start + i * chain_length)]; - dy = configs[j][3 * (chain_start + i * chain_length + chain_length - 1) + - 1] - - configs[j][3 * (chain_start + i * chain_length) + 1]; - dz = configs[j][3 * (chain_start + i * chain_length + chain_length - 1) + - 2] - - configs[j][3 * (chain_start + i * chain_length) + 2]; + dy = + configs[j] + [3 * (chain_start + i * chain_length + chain_length - 1) + 1] - + configs[j][3 * (chain_start + i * chain_length) + 1]; + dz = + configs[j] + [3 * (chain_start + i * chain_length + chain_length - 1) + 2] - + configs[j][3 * (chain_start + i * chain_length) + 2]; tmp = (Utils::sqr(dx) + Utils::sqr(dy) + Utils::sqr(dz)); dist += sqrt(tmp); dist2 += tmp; @@ -105,7 +106,7 @@ void calc_re_av(double **_re) { re[3] = sqrt(dist4 / tmp - re[2] * re[2]); } -void calc_rg(PartCfg & partCfg, double **_rg) { +void calc_rg(PartCfg &partCfg, double **_rg) { int i, j, p; double dx, dy, dz, r_CM_x, r_CM_y, r_CM_z; double r_G = 0.0, r_G2 = 0.0, r_G4 = 0.0; @@ -147,7 +148,7 @@ void calc_rg(PartCfg & partCfg, double **_rg) { rg[3] = sqrt(r_G4 / tmp - rg[2] * rg[2]); } -void calc_rg_av(PartCfg & partCfg, double **_rg) { +void calc_rg_av(PartCfg &partCfg, double **_rg) { int i, j, k, p; double dx, dy, dz, r_CM_x, r_CM_y, r_CM_z; double r_G = 0.0, r_G2 = 0.0, r_G4 = 0.0; @@ -191,13 +192,14 @@ void calc_rg_av(PartCfg & partCfg, double **_rg) { rg[3] = sqrt(r_G4 / tmp - rg[2] * rg[2]); } -void calc_rh(PartCfg & partCfg, double **_rh) { +void calc_rh(PartCfg &partCfg, double **_rh) { int i, j, p; - double dx, dy, dz, r_H = 0.0, r_H2 = 0.0, *rh = nullptr, ri = 0.0, prefac, tmp; + double dx, dy, dz, r_H = 0.0, r_H2 = 0.0, *rh = nullptr, ri = 0.0, prefac, + tmp; *_rh = rh = Utils::realloc(rh, 2 * sizeof(double)); prefac = 0.5 * chain_length * - (chain_length -1 ); /* 1/N^2 is not a normalization factor */ + (chain_length - 1); /* 1/N^2 is not a normalization factor */ for (p = 0; p < chain_n_chains; p++) { ri = 0.0; for (i = chain_start + chain_length * p; @@ -223,7 +225,8 @@ void calc_rh(PartCfg & partCfg, double **_rh) { void calc_rh_av(double **_rh) { int i, j, p, k; - double dx, dy, dz, r_H = 0.0, r_H2 = 0.0, *rh = nullptr, ri = 0.0, prefac, tmp; + double dx, dy, dz, r_H = 0.0, r_H2 = 0.0, *rh = nullptr, ri = 0.0, prefac, + tmp; *_rh = rh = Utils::realloc(rh, 2 * sizeof(double)); prefac = 0.5 * chain_length * (chain_length - 1); @@ -249,7 +252,7 @@ void calc_rh_av(double **_rh) { rh[1] = sqrt(r_H2 / tmp - rh[0] * rh[0]); } -void calc_internal_dist(PartCfg & partCfg, double **_idf) { +void calc_internal_dist(PartCfg &partCfg, double **_idf) { int i, j, k; double dx, dy, dz; double *idf = nullptr; @@ -299,7 +302,7 @@ void calc_internal_dist_av(double **_idf) { } } -void calc_bond_l(PartCfg & partCfg, double **_bond_l) { +void calc_bond_l(PartCfg &partCfg, double **_bond_l) { int i, j; double dx, dy, dz, tmp; double *bond_l = nullptr; @@ -368,7 +371,7 @@ void calc_bond_l_av(double **_bond_l) { bond_l[3] = sqrt(bond_l[3]); } -void calc_bond_dist(PartCfg & partCfg, double **_bdf, int ind_n) { +void calc_bond_dist(PartCfg &partCfg, double **_bdf, int ind_n) { int i, j = ind_n, k; double dx, dy, dz; double *bdf = nullptr; @@ -417,16 +420,14 @@ void calc_bond_dist_av(double **_bdf, int ind_n) { } } -void init_g123(PartCfg & partCfg) { +void init_g123(PartCfg &partCfg) { int i, j, p; double cm_tmp[3], M; /* Save particles' current positions (which'll be used as initial position later on) */ - partCoord_g = - Utils::realloc(partCoord_g, 3 * n_part * sizeof(float)); - partCM_g = - Utils::realloc(partCM_g, 3 * chain_n_chains * sizeof(float)); + partCoord_g = Utils::realloc(partCoord_g, 3 * n_part * sizeof(float)); + partCM_g = Utils::realloc(partCM_g, 3 * chain_n_chains * sizeof(float)); n_part_g = n_part; n_chains_g = chain_n_chains; for (j = 0; j < chain_n_chains; j++) { @@ -448,7 +449,7 @@ void init_g123(PartCfg & partCfg) { } } -void calc_g123(PartCfg & partCfg, double *_g1, double *_g2, double *_g3) { +void calc_g123(PartCfg &partCfg, double *_g1, double *_g2, double *_g3) { /* - Mean square displacement of a monomer - Mean square displacement in the center of gravity of the chain itself - Motion of the center of mass */ @@ -475,11 +476,11 @@ void calc_g123(PartCfg & partCfg, double *_g1, double *_g2, double *_g3) { Utils::sqr(partCfg[p].r.p[1] - partCoord_g[3 * p + 1]) + Utils::sqr(partCfg[p].r.p[2] - partCoord_g[3 * p + 2]); g2 += Utils::sqr((partCfg[p].r.p[0] - partCoord_g[3 * p]) - - (cm_tmp[0] - partCM_g[3 * j])) + + (cm_tmp[0] - partCM_g[3 * j])) + Utils::sqr((partCfg[p].r.p[1] - partCoord_g[3 * p + 1]) - - (cm_tmp[1] - partCM_g[3 * j + 1])) + + (cm_tmp[1] - partCM_g[3 * j + 1])) + Utils::sqr((partCfg[p].r.p[2] - partCoord_g[3 * p + 2]) - - (cm_tmp[2] - partCM_g[3 * j + 2])); + (cm_tmp[2] - partCM_g[3 * j + 2])); } g3 += Utils::sqr(cm_tmp[0] - partCM_g[3 * j]) + Utils::sqr(cm_tmp[1] - partCM_g[3 * j + 1]) + @@ -502,11 +503,12 @@ void calc_g1_av(double **_g1, int window, double weights[3]) { for (j = 0; j < chain_n_chains; j++) { for (i = 0; i < chain_length; i++) { p = chain_start + j * chain_length + i; - g1[k] += weights[0] * Utils::sqr(configs[t + k][3 * p] - configs[t][3 * p]) + - weights[1] * - Utils::sqr(configs[t + k][3 * p + 1] - configs[t][3 * p + 1]) + - weights[2] * - Utils::sqr(configs[t + k][3 * p + 2] - configs[t][3 * p + 2]); + g1[k] += weights[0] * + Utils::sqr(configs[t + k][3 * p] - configs[t][3 * p]) + + weights[1] * Utils::sqr(configs[t + k][3 * p + 1] - + configs[t][3 * p + 1]) + + weights[2] * Utils::sqr(configs[t + k][3 * p + 2] - + configs[t][3 * p + 2]); } } } @@ -514,7 +516,7 @@ void calc_g1_av(double **_g1, int window, double weights[3]) { } } -void calc_g2_av(PartCfg & partCfg, double **_g2, int window, double weights[3]) { +void calc_g2_av(PartCfg &partCfg, double **_g2, int window, double weights[3]) { int i, j, p, t, k, cnt; double *g2 = nullptr, cm_tmp[3]; double M; @@ -542,15 +544,15 @@ void calc_g2_av(PartCfg & partCfg, double **_g2, int window, double weights[3]) cm_tmp[2] /= M; for (i = 0; i < chain_length; i++) { p = chain_start + j * chain_length + i; - g2[k] += - weights[0] * - Utils::sqr((configs[t + k][3 * p] - configs[t][3 * p]) - cm_tmp[0]) + - weights[1] * - Utils::sqr((configs[t + k][3 * p + 1] - configs[t][3 * p + 1]) - - cm_tmp[1]) + - weights[2] * - Utils::sqr((configs[t + k][3 * p + 2] - configs[t][3 * p + 2]) - - cm_tmp[2]); + g2[k] += weights[0] * + Utils::sqr((configs[t + k][3 * p] - configs[t][3 * p]) - + cm_tmp[0]) + + weights[1] * Utils::sqr((configs[t + k][3 * p + 1] - + configs[t][3 * p + 1]) - + cm_tmp[1]) + + weights[2] * Utils::sqr((configs[t + k][3 * p + 2] - + configs[t][3 * p + 2]) - + cm_tmp[2]); } } } @@ -558,7 +560,7 @@ void calc_g2_av(PartCfg & partCfg, double **_g2, int window, double weights[3]) } } -void calc_g3_av(PartCfg & partCfg, double **_g3, int window, double weights[3]) { +void calc_g3_av(PartCfg &partCfg, double **_g3, int window, double weights[3]) { int i, j, p, t, k, cnt; double *g3 = nullptr, cm_tmp[3]; double M; @@ -581,7 +583,8 @@ void calc_g3_av(PartCfg & partCfg, double **_g3, int window, double weights[3]) (partCfg[p]).p.mass; M += (partCfg[p]).p.mass; } - g3[k] += (weights[0] * Utils::sqr(cm_tmp[0]) + weights[1] * Utils::sqr(cm_tmp[1]) + + g3[k] += (weights[0] * Utils::sqr(cm_tmp[0]) + + weights[1] * Utils::sqr(cm_tmp[1]) + weights[2] * Utils::sqr(cm_tmp[2])) / Utils::sqr(M); } @@ -590,12 +593,13 @@ void calc_g3_av(PartCfg & partCfg, double **_g3, int window, double weights[3]) } } -void analyze_formfactor(PartCfg & partCfg, double qmin, double qmax, int qbins, double **_ff) { +void analyze_formfactor(PartCfg &partCfg, double qmin, double qmax, int qbins, + double **_ff) { int i, j, k, qi, cnt, cnt_max; double q, qfak, qr, dx, dy, dz, *r_ij = nullptr, *ff = nullptr; *_ff = ff = Utils::realloc(ff, (qbins + 1) * sizeof(double)); - r_ij = Utils::realloc( - r_ij, chain_length * (chain_length - 1) / 2 * sizeof(double)); + r_ij = Utils::realloc(r_ij, + chain_length * (chain_length - 1) / 2 * sizeof(double)); qfak = pow((qmax / qmin), (1.0 / qbins)); for (qi = 0; qi <= qbins; qi++) @@ -637,8 +641,8 @@ void analyze_formfactor_av(double qmin, double qmax, int qbins, double **_ff) { int i, j, k, n, qi, cnt, cnt_max; double q, qfak, qr, dx, dy, dz, *r_ij = nullptr, *ff = nullptr; *_ff = ff = Utils::realloc(ff, (qbins + 1) * sizeof(double)); - r_ij = Utils::realloc( - r_ij, chain_length * (chain_length - 1) / 2 * sizeof(double)); + r_ij = Utils::realloc(r_ij, + chain_length * (chain_length - 1) / 2 * sizeof(double)); qfak = pow((qmax / qmin), (1.0 / qbins)); for (qi = 0; qi <= qbins; qi++) @@ -678,8 +682,8 @@ void analyze_formfactor_av(double qmin, double qmax, int qbins, double **_ff) { free(r_ij); } -void analyze_rdfchain(PartCfg & partCfg, double r_min, double r_max, int r_bins, double **_f1, - double **_f2, double **_f3) { +void analyze_rdfchain(PartCfg &partCfg, double r_min, double r_max, int r_bins, + double **_f1, double **_f2, double **_f3) { int i, j, ind, c_i, c_j, mon; double bin_width, inv_bin_width, factor, r_in, r_out, bin_volume, dist, chain_mass, *f1 = nullptr, *f2 = nullptr, *f3 = nullptr; @@ -757,4 +761,3 @@ void analyze_rdfchain(PartCfg & partCfg, double r_min, double r_max, int r_bins, f3[i] *= factor / bin_volume; } } - diff --git a/src/core/statistics_chain.hpp b/src/core/statistics_chain.hpp index 93f87e2dea..6d37cb9f0b 100755 --- a/src/core/statistics_chain.hpp +++ b/src/core/statistics_chain.hpp @@ -1,26 +1,26 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef STATISTICS_CHAIN_H #define STATISTICS_CHAIN_H -/** \file statistics_chain.hpp +/** \file statistics_chain.hpp This file contains the code for statistics on the data using the molecule information set with analyse set chains. @@ -45,66 +45,77 @@ extern int chain_n_chains; extern int chain_length; /*@}*/ - /** \name Exported Functions */ /************************************************************/ /*@{*/ -/** calculate the end-to-end-distance. chain information \ref chain_start etc. must be set! +/** calculate the end-to-end-distance. chain information \ref chain_start etc. + must be set! @return the end-to-end-distance */ void calc_re(PartCfg &, double **re); -/** calculate the end-to-end-distance averaged over all configurations stored in \ref #configs. +/** calculate the end-to-end-distance averaged over all configurations stored in + \ref #configs. Chain information \ref chain_start etc. must be set! @return the averaged end-to-end-distance */ void calc_re_av(double **re); -/** calculate the radius of gyration. chain information \ref chain_start etc. must be set! +/** calculate the radius of gyration. chain information \ref chain_start etc. + must be set! @return the radius of gyration */ void calc_rg(PartCfg &, double **rg); -/** calculate the radius of gyration averaged over all configurations stored in \ref #configs. +/** calculate the radius of gyration averaged over all configurations stored in + \ref #configs. Chain information \ref chain_start etc. must be set! @return the averaged radius of gyration */ void calc_rg_av(PartCfg &, double **rg); -/** calculate the hydrodynamic radius (ref. Kirkwood-Zimm theory). chain information \ref chain_start etc. must be set! +/** calculate the hydrodynamic radius (ref. Kirkwood-Zimm theory). chain + information \ref chain_start etc. must be set! @return the hydrodynamic radius */ void calc_rh(PartCfg &, double **rh); -/** calculate the hydrodynamic radius averaged over all configurations stored in \ref #configs. +/** calculate the hydrodynamic radius averaged over all configurations stored in + \ref #configs. Chain information \ref chain_start etc. must be set! @return the averaged hydrodynamic radius */ void calc_rh_av(double **rh); -/** calculates the internal distances within a chain. Chain information \ref chain_start etc. must be set! +/** calculates the internal distances within a chain. Chain information \ref + chain_start etc. must be set! @param idf contains idf[0],...,idf[chain_length-1] */ void calc_internal_dist(double **idf); -/** calculates the internal distances within a chain averaged over all configurations stored in \ref #configs. +/** calculates the internal distances within a chain averaged over all + configurations stored in \ref #configs. Chain information \ref chain_start etc. must be set! @param idf contains idf[0],...,idf[chain_length-1] */ void calc_internal_dist_av(double **idf); -/** calculates the bond length between two neighbouring monomers (i.e. idf[1] in \ref calc_internal_dist). +/** calculates the bond length between two neighbouring monomers (i.e. idf[1] in + \ref calc_internal_dist). Chain information \ref chain_start etc. must be set! @param bond_l returns the bond length */ void calc_bond_l(double **bond_l); -/** calculates the averaged bond length between two neighbouring monomers (i.e. idf[1] in \ref calc_internal_dist_av). +/** calculates the averaged bond length between two neighbouring monomers (i.e. + idf[1] in \ref calc_internal_dist_av). Chain information \ref chain_start etc. must be set! @param bond_l returns the bond length */ void calc_bond_l_av(double **bond_l); -/** calculates the internal distances within a chain measured from monomer \. +/** calculates the internal distances within a chain measured from monomer + \. Chain information \ref chain_start etc. must be set! - @param bdf contains bdf[0],...,bdf[(chain_length-1) - ind_n] + @param bdf contains bdf[0],...,bdf[(chain_length-1) - ind_n] @param ind_n the index of the monomer from where all distances are taken */ void calc_bond_dist(double **bdf, int ind_n); -/** calculates the internal distances within a chain measured from monomer \ averaged over all configurations stored in \ref #configs. +/** calculates the internal distances within a chain measured from monomer + \ averaged over all configurations stored in \ref #configs. Chain information \ref chain_start etc. must be set! - @param bdf contains bdf[0],...,bdf[(chain_length-1) - ind_n] + @param bdf contains bdf[0],...,bdf[(chain_length-1) - ind_n] @param ind_n the index of the monomer from where all distances are taken */ void calc_bond_dist_av(double **bdf, int ind_n); @@ -115,64 +126,78 @@ void calc_bond_dist_av(double **bdf, int ind_n); */ void calc_g123(double *g1, double *g2, double *g3); -/** calculate \ averaged over all configurations stored in \ref #configs. +/** calculate \ averaged over all configurations stored in \ref #configs. Chain information \ref chain_start etc. must be set! @param _g1 contains g1[0],...,g1[n_configs-1] - @param window if large than 0, the window size for a sliding window analysis - @param weights weights for the different coordinates, basically to allow to calculate 2d g1 + @param window if large than 0, the window size for a sliding window + analysis + @param weights weights for the different coordinates, basically to allow to + calculate 2d g1 */ void calc_g1_av(double **_g1, int window, double weights[3]); -/** calculate \ averaged over all configurations stored in \ref #configs. +/** calculate \ averaged over all configurations stored in \ref #configs. Chain information \ref chain_start etc. must be set! @param _g2 contains g2[0],...,g2[n_configs-1] - @param window if large than 0, the window size for a sliding window analysis - @param weights weights for the different coordinates, basically to allow to calculate 2d g1 + @param window if large than 0, the window size for a sliding window + analysis + @param weights weights for the different coordinates, basically to allow to + calculate 2d g1 */ void calc_g2_av(double **_g2, int window, double weights[3]); -/** calculate \ averaged over all configurations stored in \ref #configs. +/** calculate \ averaged over all configurations stored in \ref #configs. Chain information \ref chain_start etc. must be set! @param _g3 contains g3[0],...,g3[n_configs-1] - @param window if large than 0, the window size for a sliding window analysis - @param weights weights for the different coordinates, basically to allow to calculate 2d g1 + @param window if large than 0, the window size for a sliding window + analysis + @param weights weights for the different coordinates, basically to allow to + calculate 2d g1 */ void calc_g3_av(double **_g3, int window, double weights[3]); -//void calc_g3_av(double **g3); +// void calc_g3_av(double **g3); /** set the start configuration for g123. chain information \ref chain_start etc. must be set! */ void init_g123(); -/** Derives the spherically averaged formfactor S(q) = 1/chain_length * Sum(i,j=1..chain_length)[sin(q*r_ij)/q*r_ij] of a single chain, - averaged over all \ref chain_n_chains currently allocated (-\> chain information must be set!). +/** Derives the spherically averaged formfactor S(q) = 1/chain_length * + Sum(i,j=1..chain_length)[sin(q*r_ij)/q*r_ij] of a single chain, + averaged over all \ref chain_n_chains currently allocated (-\> chain + information must be set!). @param qmin smallest q-vector to look at (qmin \> 0) @param qmax biggest q-vector to look at (qmax \> qmin) - @param qbins decides how many S(q) are derived (note that the qbins+1 values will be logarithmically spaced) + @param qbins decides how many S(q) are derived (note that the qbins+1 values + will be logarithmically spaced) @param _ff contains S(q) as an array of size qbins */ void analyze_formfactor(double qmin, double qmax, int qbins, double **_ff); -/** Derives the spherically averaged formfactor S(q) = 1/chain_length * Sum(i,j=1..chain_length)[sin(q*r_ij)/q*r_ij] of a single chain, - averaged over all \ref chain_n_chains of all \ref n_configs stored configurations in \ref #configs. +/** Derives the spherically averaged formfactor S(q) = 1/chain_length * + Sum(i,j=1..chain_length)[sin(q*r_ij)/q*r_ij] of a single chain, + averaged over all \ref chain_n_chains of all \ref n_configs stored + configurations in \ref #configs. @param qmin smallest q-vector to look at (qmin \> 0) @param qmax biggest q-vector to look at (qmax \> qmin) - @param qbins decides how many S(q) are derived (note that the qbins+1 values will be logarithmically spaced) + @param qbins decides how many S(q) are derived (note that the qbins+1 values + will be logarithmically spaced) @param _ff contains S(q) as an array of size qbins */ void analyze_formfactor_av(double qmin, double qmax, int qbins, double **_ff); -/** Calculates monomer-monomer distribution between monomers of different chains. +/** Calculates monomer-monomer distribution between monomers of different + chains. @param r_min minimal distance for the distribution. @param r_max maximal distance for the distribution. @param r_bins the number of bins - @param _rdf contains the monomer-monomer distribution + @param _rdf contains the monomer-monomer distribution @param _rdf_cm contains the distribution of centers of mass of the chains - @param _rdf_d contains the distribution of closest distances between the chains + @param _rdf_d contains the distribution of closest distances between the + chains */ -void analyze_rdfchain(PartCfg &, double r_min, double r_max, int r_bins, double **_rdf, double **_rdf_cm, double **_rdf_d); +void analyze_rdfchain(PartCfg &, double r_min, double r_max, int r_bins, + double **_rdf, double **_rdf_cm, double **_rdf_d); /** sets the particle mol_id according to the chain_structure info*/ void update_mol_ids_setchains(); - #endif diff --git a/src/core/statistics_cluster.cpp b/src/core/statistics_cluster.cpp index 17718d9b9c..b251a03069 100755 --- a/src/core/statistics_cluster.cpp +++ b/src/core/statistics_cluster.cpp @@ -1,174 +1,188 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ - #include "statistics_cluster.hpp" #include "grid.hpp" #include "interaction_data.hpp" -/** nullptr terminated linked list of elements of a cluster (indices in particle list) */ +/** nullptr terminated linked list of elements of a cluster (indices in particle + * list) */ ClusterElement *element; /** Double linked list of \ref statistics_cluster::Cluster */ -Cluster *cluster; +Cluster *cluster; /** first cluster in list of \ref statistics_cluster::Cluster */ -Cluster *first_cluster; +Cluster *first_cluster; /** last cluster in list of \ref statistics_cluster::Cluster */ -Cluster *last_cluster; - +Cluster *last_cluster; /** \name Routines */ /************************************************************/ /*@{*/ - /* HOLE CLUSTER ALGORITHM */ -/** test if a mesh point belongs to free (return -1) or occupied (return -2) volume. +/** test if a mesh point belongs to free (return -1) or occupied (return -2) +volume. Needs feature LENNARD_JONES compiled in. */ -int test_mesh_elements(PartCfg & partCfg, double pos[3], int probe_part_type) -{ +int test_mesh_elements(PartCfg &partCfg, double pos[3], int probe_part_type) { #ifdef LENNARD_JONES - double dist,vec[3]; + double dist, vec[3]; - for (auto &p: partCfg) { - IA_parameters *ia_params = get_ia_param(p.p.type,probe_part_type); + for (auto &p : partCfg) { + IA_parameters *ia_params = get_ia_param(p.p.type, probe_part_type); get_mi_vector(vec, pos, p.r.p); dist = sqrt(sqrlen(vec)); - if ( dist < (ia_params->LJ_cut+ia_params->LJ_offset) ) return -2; - + if (dist < (ia_params->LJ_cut + ia_params->LJ_offset)) + return -2; } #endif return -1; -} - +} -/** Test which mesh points belong to the free and occupied volume. +/** Test which mesh points belong to the free and occupied volume. Free volume is marked by -1 and occupied volume by -2. Needs feature LENNARD_JONES compiled in. */ -void create_free_volume_grid(PartCfg & partCfg, IntList mesh, int dim[3], int probe_part_type) -{ - int i,ix=0,iy=0,iz=0; +void create_free_volume_grid(PartCfg &partCfg, IntList mesh, int dim[3], + int probe_part_type) { + int i, ix = 0, iy = 0, iz = 0; double pos[3]; double mesh_c[3]; - for ( i=0; i<3; i++) mesh_c[i] = box_l[i] / (double)dim[i]; + for (i = 0; i < 3; i++) + mesh_c[i] = box_l[i] / (double)dim[i]; - for ( i=0; i<(dim[0]*dim[1]*dim[2]); i++) { - - pos[0] = (ix+0.5)*mesh_c[0]; - pos[1] = (iy+0.5)*mesh_c[1]; - pos[2] = (iz+0.5)*mesh_c[2]; - - mesh.e[i] = test_mesh_elements(partCfg, pos, probe_part_type); + for (i = 0; i < (dim[0] * dim[1] * dim[2]); i++) { - ix++; - if ( ix >= dim[0]) { ix = ix - dim[0]; iy++; } - if ( iy >= dim[1]) { iy = iy - dim[1]; iz++; } - } + pos[0] = (ix + 0.5) * mesh_c[0]; + pos[1] = (iy + 0.5) * mesh_c[1]; + pos[2] = (iz + 0.5) * mesh_c[2]; + mesh.e[i] = test_mesh_elements(partCfg, pos, probe_part_type); + ix++; + if (ix >= dim[0]) { + ix = ix - dim[0]; + iy++; + } + if (iy >= dim[1]) { + iy = iy - dim[1]; + iz++; + } + } } -void cluster_neighbors(int point, int dim[3], int neighbors[6]) -{ - int x,y,z,a; +void cluster_neighbors(int point, int dim[3], int neighbors[6]) { + int x, y, z, a; get_grid_pos(point, &x, &y, &z, dim); - a = x-1; if ( a<0 ) a = dim[0]-1; + a = x - 1; + if (a < 0) + a = dim[0] - 1; neighbors[0] = get_linear_index(a, y, z, dim); - a = x+1; if ( a==dim[0] ) a = 0; + a = x + 1; + if (a == dim[0]) + a = 0; neighbors[1] = get_linear_index(a, y, z, dim); - a = y-1; if ( a<0 ) a = dim[1]-1; + a = y - 1; + if (a < 0) + a = dim[1] - 1; neighbors[2] = get_linear_index(x, a, z, dim); - a = y+1; if ( a==dim[1] ) a = 0; + a = y + 1; + if (a == dim[1]) + a = 0; neighbors[3] = get_linear_index(x, a, z, dim); - a = z-1; if ( a<0 ) a = dim[2]-1; + a = z - 1; + if (a < 0) + a = dim[2] - 1; neighbors[4] = get_linear_index(x, y, a, dim); - a = z+1; if ( a==dim[2] ) a = 0; + a = z + 1; + if (a == dim[2]) + a = 0; neighbors[5] = get_linear_index(x, y, a, dim); - } -/** hole cluster algorithm. - returns the number of holes and a list of mesh points belonging to each of them */ -int cluster_free_volume_grid(IntList mesh, int dim[3], int ***holes) -{ - int i=0,j, k, n=-1, li; +/** hole cluster algorithm. + returns the number of holes and a list of mesh points belonging to each of + them */ +int cluster_free_volume_grid(IntList mesh, int dim[3], int ***holes) { + int i = 0, j, k, n = -1, li; int neighbors[6]; - - int *tmp = (int *) Utils::malloc( sizeof(int)* (dim[0]*dim[1]*dim[2])); - int *sizes = (int *) Utils::malloc( sizeof(int)* (dim[0]*dim[1]*dim[2])); - + + int *tmp = (int *)Utils::malloc(sizeof(int) * (dim[0] * dim[1] * dim[2])); + int *sizes = (int *)Utils::malloc(sizeof(int) * (dim[0] * dim[1] * dim[2])); // step 1 go through all mesh points - while ( i < (dim[0]*dim[1]*dim[2]) ) { + while (i < (dim[0] * dim[1] * dim[2])) { // step 2 test if mesh point is occupied or allready assigned - if ( mesh.e[i] == -2 || mesh.e[i] >= 0 ) { i++; } - else { + if (mesh.e[i] == -2 || mesh.e[i] >= 0) { + i++; + } else { // step 3 mesh point is free, create a new cluster n++; mesh.e[i] = n; - // start new cluster, put mesh point as first element, and set list pointer on first element + // start new cluster, put mesh point as first element, and set list + // pointer on first element sizes[n] = 1; tmp[0] = i; li = 0; // step 4 go through all elements of the cluster - while ( li < sizes[n] ) { - // step 5 go through all neighbors - j = tmp[li]; - cluster_neighbors(j, dim, neighbors); - for ( k=0; k<6; k++ ) { - // step 5 b test if status is free and append it to the cluster - if ( mesh.e[ neighbors[k] ] == -1 ) { - mesh.e[ neighbors[k] ] = n; - // append mesh point as element in the list - tmp[ sizes[n] ] = neighbors[k]; - sizes[n]++; - } - if ( mesh.e[ neighbors[k] ] > 0 && mesh.e[ neighbors[k] ] 0 && mesh.e[neighbors[k]] < n) { + fprintf(stderr, + "cfvg:error: i=%d, li=%d, n=%d, mesh.e[x]=%d, x=%d\n", i, + li, n, mesh.e[neighbors[k]], neighbors[k]); + fflush(stderr); + } + } + li++; } } - - } - + } // allocate list space - (*holes) = (int **) Utils::malloc ( sizeof(int *)*(n+1) ); - for ( i=0; i<=n; i++ ) { - (*holes)[i] = (int *) Utils::malloc ( sizeof(int)*(sizes[i]+1) ); + (*holes) = (int **)Utils::malloc(sizeof(int *) * (n + 1)); + for (i = 0; i <= n; i++) { + (*holes)[i] = (int *)Utils::malloc(sizeof(int) * (sizes[i] + 1)); (*holes)[i][0] = 0; } - for ( i=0; i<(dim[0]*dim[1]*dim[2]); i++ ) { + for (i = 0; i < (dim[0] * dim[1] * dim[2]); i++) { j = mesh.e[i]; - if ( j >= 0 ) { - (*holes)[j][0] ++; - (*holes)[j][ (*holes)[j][0] ] = i; + if (j >= 0) { + (*holes)[j][0]++; + (*holes)[j][(*holes)[j][0]] = i; } } @@ -179,27 +193,30 @@ int cluster_free_volume_grid(IntList mesh, int dim[3], int ***holes) } /** Calculates the surface to volume ratios of the holes */ -void cluster_free_volume_surface(IntList mesh, int dim[3], int nholes, int **holes, int *surface) -{ +void cluster_free_volume_surface(IntList mesh, int dim[3], int nholes, + int **holes, int *surface) { int i, j, n, neighbors[6], inner; - for ( i=0; i= 0 ) { + if (n >= 0) { inner = 1; cluster_neighbors(i, dim, neighbors); // check if all neighbors belong to the same cluster - for ( j=0; j<6; j++ ) { - if ( mesh.e[ neighbors[j] ] != n ) inner = 0; + for (j = 0; j < 6; j++) { + if (mesh.e[neighbors[j]] != n) + inner = 0; + } + if (inner == 0) { + surface[n] += 1.0; } - if ( inner == 0 ) { surface[n]+=1.0; } } } - } /*@}*/ diff --git a/src/core/statistics_cluster.hpp b/src/core/statistics_cluster.hpp index 24f3f0a4e7..7a29f311c6 100755 --- a/src/core/statistics_cluster.hpp +++ b/src/core/statistics_cluster.hpp @@ -1,61 +1,61 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef STATISTICS_CLUSTER_H #define STATISTICS_CLUSTER_H /** \file statistics_cluster.hpp * - * mesh based cluster algorithm to identify hole spaces - * (see thesis chapter 3 of H. Schmitz for details) + * mesh based cluster algorithm to identify hole spaces + * (see thesis chapter 3 of H. Schmitz for details) */ -#include "particle_data.hpp" #include "PartCfg.hpp" +#include "particle_data.hpp" /** \name Data structures */ /************************************************************/ /*@{*/ /** Structure for cluster element */ -struct StructClusterElement{ - /** Element identity */ - int id; - /** Pointer to next cluster element.*/ - struct StructClusterElement *next; +struct StructClusterElement { + /** Element identity */ + int id; + /** Pointer to next cluster element.*/ + struct StructClusterElement *next; }; /** Cluster Element */ typedef struct StructClusterElement ClusterElement; /** Structure for Cluster */ -struct StructCluster { - /** Cluster identity */ - int id; - /** Cluster size */ - int size; - /** Pointer to first cluster element.*/ - ClusterElement *first; - /** Pointer to next cluster */ - struct StructCluster *next; - /** Pointer to previous cluster */ - struct StructCluster *prev; +struct StructCluster { + /** Cluster identity */ + int id; + /** Cluster size */ + int size; + /** Pointer to first cluster element.*/ + ClusterElement *first; + /** Pointer to next cluster */ + struct StructCluster *next; + /** Pointer to previous cluster */ + struct StructCluster *prev; }; /** Cluster */ @@ -67,17 +67,19 @@ typedef struct StructCluster Cluster; /************************************************************/ /*@{*/ -/** nullptr terminated linked list of elements of a cluster (indices in particle list) */ +/** nullptr terminated linked list of elements of a cluster (indices in particle + * list) */ extern ClusterElement *element; /** Double linked list of \ref statistics_cluster::Cluster */ -extern Cluster *cluster; +extern Cluster *cluster; /** first cluster in list of \ref statistics_cluster::Cluster */ -extern Cluster *first_cluster; +extern Cluster *first_cluster; /** last cluster in list of \ref statistics_cluster::Cluster */ -extern Cluster *last_cluster; +extern Cluster *last_cluster; void create_free_volume_grid(IntList mesh, int dim[3], int probe_part_type); int cluster_free_volume_grid(IntList mesh, int dim[3], int ***holes); -void cluster_free_volume_surface(IntList mesh, int dim[3], int nholes, int **holes, int *surface); +void cluster_free_volume_surface(IntList mesh, int dim[3], int nholes, + int **holes, int *surface); #endif diff --git a/src/core/statistics_fluid.hpp b/src/core/statistics_fluid.hpp index 3e5af4cf6f..e13eb69615 100755 --- a/src/core/statistics_fluid.hpp +++ b/src/core/statistics_fluid.hpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file statistics_fluid.hpp * diff --git a/src/core/steppot.cpp b/src/core/steppot.cpp index 26da8e7526..b96d1b4ce4 100755 --- a/src/core/steppot.cpp +++ b/src/core/steppot.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file steppot.cpp * @@ -27,22 +27,20 @@ #ifdef SMOOTH_STEP #include "communication.hpp" -int smooth_step_set_params(int part_type_a, int part_type_b, - double d, int n, double eps, - double k0, double sig, - double cut) -{ +int smooth_step_set_params(int part_type_a, int part_type_b, double d, int n, + double eps, double k0, double sig, double cut) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) return ES_ERROR; - - data->SmSt_eps = eps; - data->SmSt_sig = sig; - data->SmSt_cut = cut; - data->SmSt_d = d; - data->SmSt_n = n; - data->SmSt_k0 = k0; - + + if (!data) + return ES_ERROR; + + data->SmSt_eps = eps; + data->SmSt_sig = sig; + data->SmSt_cut = cut; + data->SmSt_d = d; + data->SmSt_n = n; + data->SmSt_k0 = k0; + /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); diff --git a/src/core/steppot.hpp b/src/core/steppot.hpp index 8c6ffb2051..d94f5ce401 100755 --- a/src/core/steppot.hpp +++ b/src/core/steppot.hpp @@ -27,9 +27,9 @@ * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef SMOOTH_STEP diff --git a/src/core/subt_lj.cpp b/src/core/subt_lj.cpp index 652985b0b6..3398e58ac4 100755 --- a/src/core/subt_lj.cpp +++ b/src/core/subt_lj.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file subt_lj.cpp * @@ -27,9 +27,8 @@ #ifdef LENNARD_JONES #include "communication.hpp" -int subt_lj_set_params(int bond_type) -{ - if(bond_type < 0) +int subt_lj_set_params(int bond_type) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -43,4 +42,3 @@ int subt_lj_set_params(int bond_type) } #endif - diff --git a/src/core/swimmer_reaction.cpp b/src/core/swimmer_reaction.cpp index c05275467e..795258f316 100755 --- a/src/core/swimmer_reaction.cpp +++ b/src/core/swimmer_reaction.cpp @@ -24,14 +24,14 @@ #include "swimmer_reaction.hpp" #include "cells.hpp" +#include "communication.hpp" #include "errorhandling.hpp" #include "forces.hpp" +#include "grid.hpp" #include "initialize.hpp" -#include "utils.hpp" -#include "random.hpp" -#include "communication.hpp" #include "integrate.hpp" -#include "grid.hpp" +#include "random.hpp" +#include "utils.hpp" #include #include @@ -44,7 +44,8 @@ reaction_struct reaction; void reactions_sanity_checks() { if (reaction.ct_rate != 0.0) { - if (!cell_structure.use_verlet_list || cell_structure.type != CELL_STRUCTURE_DOMDEC) { + if (!cell_structure.use_verlet_list || + cell_structure.type != CELL_STRUCTURE_DOMDEC) { runtimeErrorMsg() << "The SWIMMER_REACTIONS feature requires verlet " "lists and domain decomposition"; } @@ -116,7 +117,7 @@ void integrate_reaction_noswap() { if (check_catalyzer != 0) { for (auto &pair : cell->m_verlet_list) { - auto p1 = pair.first; // pointer to particle 1 + auto p1 = pair.first; // pointer to particle 1 auto p2 = pair.second; // pointer to particle 2 if ((p1->p.type == reaction.reactant_type && @@ -141,40 +142,40 @@ void integrate_reaction_noswap() { } } - /* Now carry out the reaction on the particles which are tagged */ - for (int c = 0; c < local_cells.n; c++) { - auto cell = local_cells.cell[c]; - auto p1 = cell->part; - auto np = cell->n; + /* Now carry out the reaction on the particles which are tagged */ + for (int c = 0; c < local_cells.n; c++) { + auto cell = local_cells.cell[c]; + auto p1 = cell->part; + auto np = cell->n; - for (int i = 0; i < np; i++) { - if (p1[i].p.type == reaction.reactant_type) { + for (int i = 0; i < np; i++) { + if (p1[i].p.type == reaction.reactant_type) { - if (p1[i].p.catalyzer_count > 0) { + if (p1[i].p.catalyzer_count > 0) { - if (reaction.sing_mult == 0) { - rand = d_random(); + if (reaction.sing_mult == 0) { + rand = d_random(); - bernoulli = pow(ct_ratexp, p1[i].p.catalyzer_count); + bernoulli = pow(ct_ratexp, p1[i].p.catalyzer_count); - if (rand > bernoulli) { - p1[i].p.type = reaction.product_type; - } + if (rand > bernoulli) { + p1[i].p.type = reaction.product_type; + } - } else /* We only consider each reactant once */ - { - rand = d_random(); + } else /* We only consider each reactant once */ + { + rand = d_random(); - if (rand > ct_ratexp) { - p1[i].p.type = reaction.product_type; + if (rand > ct_ratexp) { + p1[i].p.type = reaction.product_type; + } } - } - p1[i].p.catalyzer_count = 0; + p1[i].p.catalyzer_count = 0; + } } } } - } /* We only need to do something when the equilibrium reaction rate constant is nonzero */ diff --git a/src/core/swimmer_reaction.hpp b/src/core/swimmer_reaction.hpp index 566edcad96..46c4a8fb0f 100755 --- a/src/core/swimmer_reaction.hpp +++ b/src/core/swimmer_reaction.hpp @@ -1,31 +1,31 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef SWIMMER_REACTION_H #define SWIMMER_REACTION_H /** \file swimmer_reaction.hpp * */ - -#include "utils.hpp" + #include "particle_data.hpp" +#include "utils.hpp" typedef struct { int reactant_type; @@ -36,7 +36,7 @@ typedef struct { double eq_rate; int sing_mult; int swap; -} reaction_struct; +} reaction_struct; extern reaction_struct reaction; diff --git a/src/core/thermalized_bond.cpp b/src/core/thermalized_bond.cpp index 410b22948e..c8c538d7cf 100644 --- a/src/core/thermalized_bond.cpp +++ b/src/core/thermalized_bond.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file thermalized_bond.cpp * @@ -30,8 +30,9 @@ int n_thermalized_bonds = 0; -int thermalized_bond_set_params(int bond_type, double temp_com, double gamma_com, double temp_distance, double gamma_distance, double r_cut) -{ +int thermalized_bond_set_params(int bond_type, double temp_com, + double gamma_com, double temp_distance, + double gamma_distance, double r_cut) { if (bond_type < 0) return ES_ERROR; @@ -40,20 +41,23 @@ int thermalized_bond_set_params(int bond_type, double temp_com, double gamma_com bonded_ia_params[bond_type].p.thermalized_bond.temp_com = temp_com; bonded_ia_params[bond_type].p.thermalized_bond.gamma_com = gamma_com; bonded_ia_params[bond_type].p.thermalized_bond.temp_distance = temp_distance; - bonded_ia_params[bond_type].p.thermalized_bond.gamma_distance = gamma_distance; + bonded_ia_params[bond_type].p.thermalized_bond.gamma_distance = + gamma_distance; bonded_ia_params[bond_type].p.thermalized_bond.r_cut = r_cut; - + bonded_ia_params[bond_type].p.thermalized_bond.pref1_com = gamma_com; - bonded_ia_params[bond_type].p.thermalized_bond.pref2_com = sqrt(24.0 * gamma_com / time_step * temp_com); + bonded_ia_params[bond_type].p.thermalized_bond.pref2_com = + sqrt(24.0 * gamma_com / time_step * temp_com); bonded_ia_params[bond_type].p.thermalized_bond.pref1_dist = gamma_distance; - bonded_ia_params[bond_type].p.thermalized_bond.pref2_dist = sqrt(24.0 * gamma_distance / time_step * temp_distance); + bonded_ia_params[bond_type].p.thermalized_bond.pref2_dist = + sqrt(24.0 * gamma_distance / time_step * temp_distance); bonded_ia_params[bond_type].type = BONDED_IA_THERMALIZED_DIST; bonded_ia_params[bond_type].num = 1; n_thermalized_bonds += 1; - mpi_bcast_ia_params(bond_type, -1); + mpi_bcast_ia_params(bond_type, -1); mpi_bcast_parameter(FIELD_THERMALIZEDBONDS); return ES_OK; @@ -69,28 +73,27 @@ void thermalized_bond_cool_down() { thermalized_bond_update_params(pref_scale); } -void thermalized_bond_init() -{ +void thermalized_bond_init() { for (int i = 0; i < bonded_ia_params.size(); i++) { - if (bonded_ia_params[i].type == BONDED_IA_THERMALIZED_DIST) { - Thermalized_bond_parameters &t = bonded_ia_params[i].p.thermalized_bond; - t.pref1_com = t.gamma_com; - t.pref2_com = sqrt(24.0 * t.gamma_com / time_step * t.temp_com); - t.pref1_dist = t.gamma_distance; - t.pref2_dist = sqrt(24.0 * t.gamma_distance / time_step * t.temp_distance); + if (bonded_ia_params[i].type == BONDED_IA_THERMALIZED_DIST) { + Thermalized_bond_parameters &t = bonded_ia_params[i].p.thermalized_bond; + t.pref1_com = t.gamma_com; + t.pref2_com = sqrt(24.0 * t.gamma_com / time_step * t.temp_com); + t.pref1_dist = t.gamma_distance; + t.pref2_dist = + sqrt(24.0 * t.gamma_distance / time_step * t.temp_distance); } } } - void thermalized_bond_update_params(double pref_scale) { - + for (int i = 0; i < bonded_ia_params.size(); i++) { - if (bonded_ia_params[i].type == BONDED_IA_THERMALIZED_DIST) { - Thermalized_bond_parameters &t = bonded_ia_params[i].p.thermalized_bond; - t.pref2_com *= pref_scale; - t.pref2_dist *= pref_scale; + if (bonded_ia_params[i].type == BONDED_IA_THERMALIZED_DIST) { + Thermalized_bond_parameters &t = bonded_ia_params[i].p.thermalized_bond; + t.pref2_com *= pref_scale; + t.pref2_dist *= pref_scale; } } } diff --git a/src/core/thermalized_bond.hpp b/src/core/thermalized_bond.hpp index 3ae3b42bea..ac21f955e8 100644 --- a/src/core/thermalized_bond.hpp +++ b/src/core/thermalized_bond.hpp @@ -1,23 +1,23 @@ /* Copyright (C) 2010,2012,2013 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef THERMALIZED_DIST_H @@ -30,14 +30,16 @@ /** number of thermalized bonds */ extern int n_thermalized_bonds; -#include "utils.hpp" -#include "interaction_data.hpp" +#include "debug.hpp" #include "integrate.hpp" +#include "interaction_data.hpp" #include "random.hpp" -#include "debug.hpp" +#include "utils.hpp" // Set the parameters for the thermalized bond -int thermalized_bond_set_params(int bond_type, double temp_com, double gamma_com, double temp_distance, double gamma_distance, double r_cut); +int thermalized_bond_set_params(int bond_type, double temp_com, + double gamma_com, double temp_distance, + double gamma_distance, double r_cut); void thermalized_bond_heat_up(); void thermalized_bond_cool_down(); @@ -45,7 +47,7 @@ void thermalized_bond_update_params(double pref_scale); void thermalized_bond_init(); /** Seperately thermalizes the com and distance of a particle pair - and adds this force to the particle forces. + and adds this force to the particle forces. @param p1 Pointer to first particle. @param p2 Pointer to second/middle particle. @param iaparams Parameters of interaction @@ -54,53 +56,63 @@ void thermalized_bond_init(); @return true if bond is broken */ -inline int calc_thermalized_bond_forces(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, double dx[3], double force1[3], double force2[3]) -{ - //Bond broke? - double dist = Utils::veclen(dx); - if (iaparams->p.thermalized_bond.r_cut > 0.0 && dist > iaparams->p.thermalized_bond.r_cut) { - return 1; +inline int calc_thermalized_bond_forces(Particle *p1, Particle *p2, + Bonded_ia_parameters *iaparams, + double dx[3], double force1[3], + double force2[3]) { + // Bond broke? + double dist = Utils::veclen(dx); + if (iaparams->p.thermalized_bond.r_cut > 0.0 && + dist > iaparams->p.thermalized_bond.r_cut) { + return 1; + } + + double force_lv_com, force_lv_dist, com_vel, dist_vel; + double mass_tot = p1->p.mass + p2->p.mass; + double mass_tot_inv = 1.0 / mass_tot; + double sqrt_mass_tot = sqrt(mass_tot); + double sqrt_mass_red = sqrt(p1->p.mass * p2->p.mass / mass_tot); + + for (int i = 0; i < 3; i++) { + + // Langevin thermostat for center of mass + com_vel = + mass_tot_inv * (p1->p.mass * p1->m.v[i] + p2->p.mass * p2->m.v[i]); + if (iaparams->p.thermalized_bond.pref2_com > 0.0) { + force_lv_com = -iaparams->p.thermalized_bond.pref1_com * com_vel + + sqrt_mass_tot * iaparams->p.thermalized_bond.pref2_com * + (d_random() - 0.5); + } else { + force_lv_com = -iaparams->p.thermalized_bond.pref1_com * com_vel; } - double force_lv_com, force_lv_dist, com_vel, dist_vel; - double mass_tot = p1->p.mass + p2->p.mass; - double mass_tot_inv = 1.0 / mass_tot; - double sqrt_mass_tot = sqrt(mass_tot); - double sqrt_mass_red = sqrt(p1->p.mass * p2->p.mass / mass_tot); - - for (int i=0; i<3; i++) { - - //Langevin thermostat for center of mass - com_vel = mass_tot_inv * (p1->p.mass * p1->m.v[i] + p2->p.mass * p2->m.v[i]); - if (iaparams->p.thermalized_bond.pref2_com > 0.0) { - force_lv_com = -iaparams->p.thermalized_bond.pref1_com * com_vel + sqrt_mass_tot * iaparams->p.thermalized_bond.pref2_com * (d_random()-0.5); - } else { - force_lv_com = -iaparams->p.thermalized_bond.pref1_com * com_vel; - } - - //Langevin thermostat for distance p1->p2 - dist_vel = p2->m.v[i] - p1->m.v[i]; - if (iaparams->p.thermalized_bond.pref2_dist > 0.0) { - force_lv_dist = -iaparams->p.thermalized_bond.pref1_dist * dist_vel + sqrt_mass_red * iaparams->p.thermalized_bond.pref2_dist * (d_random()-0.5); - } else { - force_lv_dist = -iaparams->p.thermalized_bond.pref1_dist * dist_vel; - } - //Add forces - force1[i] = p1->p.mass * mass_tot_inv * force_lv_com - force_lv_dist; - force2[i] = p2->p.mass * mass_tot_inv * force_lv_com + force_lv_dist; - + // Langevin thermostat for distance p1->p2 + dist_vel = p2->m.v[i] - p1->m.v[i]; + if (iaparams->p.thermalized_bond.pref2_dist > 0.0) { + force_lv_dist = -iaparams->p.thermalized_bond.pref1_dist * dist_vel + + sqrt_mass_red * iaparams->p.thermalized_bond.pref2_dist * + (d_random() - 0.5); + } else { + force_lv_dist = -iaparams->p.thermalized_bond.pref1_dist * dist_vel; } - - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: THERMALIZED BOND f = (%.3e,%.3e,%.3e)\n",this_node,p1->f.f[0]+force1[0],p1->f.f[1]+force1[1],p1->f.f[2]+force1[2])); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: THERMALIZED BOND f = (%.3e,%.3e,%.3e)\n",this_node,p2->f.f[0]+force2[0],p2->f.f[1]+force2[1],p2->f.f[2]+force2[2])); - return 0; - + // Add forces + force1[i] = p1->p.mass * mass_tot_inv * force_lv_com - force_lv_dist; + force2[i] = p2->p.mass * mass_tot_inv * force_lv_com + force_lv_dist; + } + + ONEPART_TRACE(if (p1->p.identity == check_id) fprintf( + stderr, "%d: OPT: THERMALIZED BOND f = (%.3e,%.3e,%.3e)\n", this_node, + p1->f.f[0] + force1[0], p1->f.f[1] + force1[1], p1->f.f[2] + force1[2])); + ONEPART_TRACE(if (p2->p.identity == check_id) fprintf( + stderr, "%d: OPT: THERMALIZED BOND f = (%.3e,%.3e,%.3e)\n", this_node, + p2->f.f[0] + force2[0], p2->f.f[1] + force2[1], p2->f.f[2] + force2[2])); + return 0; } - -inline int thermalized_bond_energy(const Particle *p1, const Particle *p2, const Bonded_ia_parameters *iaparams, double dx[3], double *_energy) -{ - return 0; +inline int thermalized_bond_energy(const Particle *p1, const Particle *p2, + const Bonded_ia_parameters *iaparams, + double dx[3], double *_energy) { + return 0; } #endif diff --git a/src/core/thermostat.cpp b/src/core/thermostat.cpp index da6d1142e4..6008f839ec 100755 --- a/src/core/thermostat.cpp +++ b/src/core/thermostat.cpp @@ -23,14 +23,14 @@ */ #include "thermostat.hpp" #include "communication.hpp" -#include "npt.hpp" +#include "dpd.hpp" #include "ghmc.hpp" #include "lb.hpp" +#include "npt.hpp" #include "thermalized_bond.hpp" -#include "dpd.hpp" -#include #include +#include #include /* thermostat switch */ @@ -44,9 +44,9 @@ bool thermo_virtual = true; using Thermostat::GammaType; namespace { - /* These functions return the sentinel value for the - langevin params, indicating that they have not been - set yet. */ +/* These functions return the sentinel value for the + langevin params, indicating that they have not been + set yet. */ constexpr double sentinel(double) { return -1.0; } Vector3d sentinel(Vector3d) { return {-1.0, -1.0, -1.0}; } } @@ -101,15 +101,16 @@ void thermo_init_langevin() { #ifdef PARTICLE_ANISOTROPY #ifdef ROTATION - THERMO_TRACE( - fprintf(stderr, "%d: thermo_init_langevin: langevin_gamma_rotation=(%f,%f,%f), " - "langevin_pref2_rotation=(%f,%f,%f)", - this_node, langevin_gamma_rotation[0], langevin_gamma_rotation[1], - langevin_gamma_rotation[2], langevin_pref2_rotation[0], - langevin_pref2_rotation[1], langevin_pref2_rotation[2])); + THERMO_TRACE(fprintf( + stderr, "%d: thermo_init_langevin: langevin_gamma_rotation=(%f,%f,%f), " + "langevin_pref2_rotation=(%f,%f,%f)", + this_node, langevin_gamma_rotation[0], langevin_gamma_rotation[1], + langevin_gamma_rotation[2], langevin_pref2_rotation[0], + langevin_pref2_rotation[1], langevin_pref2_rotation[2])); #endif THERMO_TRACE(fprintf( - stderr, "%d: thermo_init_langevin: langevin_pref1=(%f,%f,%f), langevin_pref2=(%f,%f,%f)", + stderr, "%d: thermo_init_langevin: langevin_pref1=(%f,%f,%f), " + "langevin_pref2=(%f,%f,%f)", this_node, langevin_pref1[0], langevin_pref1[1], langevin_pref1[2], langevin_pref2[0], langevin_pref2[1], langevin_pref2[2])); #else @@ -130,8 +131,7 @@ void thermo_init_npt_isotropic() { if (nptiso.piston != 0.0) { nptiso_pref1 = -nptiso_gamma0 * 0.5 * time_step; - nptiso_pref2 = - sqrt(12.0 * temperature * nptiso_gamma0 * time_step); + nptiso_pref2 = sqrt(12.0 * temperature * nptiso_gamma0 * time_step); nptiso_pref3 = -nptiso_gammav * (1.0 / nptiso.piston) * 0.5 * time_step; nptiso_pref4 = sqrt(12.0 * temperature * nptiso_gammav * time_step); THERMO_TRACE(fprintf( @@ -149,7 +149,7 @@ void thermo_init_npt_isotropic() { void thermo_init() { - // Init thermalized bond despite of thermostat + // Init thermalized bond despite of thermostat if (n_thermalized_bonds) { thermalized_bond_init(); } @@ -157,9 +157,11 @@ void thermo_init() { if (thermo_switch == THERMO_OFF) { return; } - if(thermo_switch & THERMO_LANGEVIN ) thermo_init_langevin(); + if (thermo_switch & THERMO_LANGEVIN) + thermo_init_langevin(); #ifdef DPD - if(thermo_switch & THERMO_DPD) dpd_init(); + if (thermo_switch & THERMO_DPD) + dpd_init(); #endif #ifdef NPT if (thermo_switch & THERMO_NPT_ISO) @@ -191,7 +193,6 @@ void thermo_heat_up() { if (n_thermalized_bonds) { thermalized_bond_heat_up(); } - } void langevin_cool_down() { diff --git a/src/core/thermostat.hpp b/src/core/thermostat.hpp index 0e9b1a6cf2..f6eb8f99eb 100755 --- a/src/core/thermostat.hpp +++ b/src/core/thermostat.hpp @@ -27,14 +27,14 @@ #include "config.hpp" #include "debug.hpp" +#include "integrate.hpp" #include "particle_data.hpp" #include "random.hpp" -#include "integrate.hpp" #include "Vector.hpp" +#include "grid.hpp" #include -#include "grid.hpp" /** \name Thermostat switches*/ /************************************************************/ @@ -159,8 +159,9 @@ inline void thermo_convert_forces_body_to_space(Particle *p, double *force) { A[2 + 3 * 2] * p->f.f[2]; } -inline void thermo_convert_vel_space_to_body(Particle *p, const Vector3d& vel_space, - Vector3d& vel_body) { +inline void thermo_convert_vel_space_to_body(Particle *p, + const Vector3d &vel_space, + Vector3d &vel_body) { double A[9]; thermo_define_rotation_matrix(p, A); @@ -294,7 +295,7 @@ inline void friction_thermo_langevin(Particle *p) { #ifndef PARTICLE_ANISOTROPY if (langevin_pref2_temp > 0.0) { p->f.f[j] = langevin_pref1_temp * velocity[j] + - langevin_pref2_temp * Thermostat::noise(); + langevin_pref2_temp * Thermostat::noise(); } else { p->f.f[j] = langevin_pref1_temp * velocity[j]; } @@ -304,14 +305,14 @@ inline void friction_thermo_langevin(Particle *p) { if (aniso_flag) { if (langevin_pref2_temp[j] > 0.0) { p->f.f[j] = langevin_pref1_temp[j] * velocity_body[j] + - langevin_pref2_temp[j] * Thermostat::noise(); + langevin_pref2_temp[j] * Thermostat::noise(); } else { p->f.f[j] = langevin_pref1_temp[j] * velocity_body[j]; } } else { if (langevin_pref2_temp[j] > 0.0) { p->f.f[j] = langevin_pref1_temp[j] * velocity[j] + - langevin_pref2_temp[j] * Thermostat::noise(); + langevin_pref2_temp[j] * Thermostat::noise(); } else { p->f.f[j] = langevin_pref1_temp[j] * velocity[j]; } @@ -394,16 +395,15 @@ inline void friction_thermo_langevin_rotation(Particle *p) { for (int j = 0; j < 3; j++) { #ifdef PARTICLE_ANISOTROPY if (langevin_pref2_temp[j] > 0.0) { - p->f.torque[j] = - -langevin_pref1_temp[j] * p->m.omega[j] + - langevin_pref2_temp[j] * Thermostat::noise(); + p->f.torque[j] = -langevin_pref1_temp[j] * p->m.omega[j] + + langevin_pref2_temp[j] * Thermostat::noise(); } else { p->f.torque[j] = -langevin_pref1_temp[j] * p->m.omega[j]; } #else if (langevin_pref2_temp > 0.0) { p->f.torque[j] = -langevin_pref1_temp * p->m.omega[j] + - langevin_pref2_temp * Thermostat::noise(); + langevin_pref2_temp * Thermostat::noise(); } else { p->f.torque[j] = -langevin_pref1_temp * p->m.omega[j]; } diff --git a/src/core/thole.cpp b/src/core/thole.cpp index 68686595f6..7a905f07f1 100755 --- a/src/core/thole.cpp +++ b/src/core/thole.cpp @@ -1,42 +1,43 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#include "utils.hpp" #include "thole.hpp" +#include "utils.hpp" #ifdef THOLE #include "communication.hpp" -int thole_set_params(int part_type_a, int part_type_b, double scaling_coeff, double q1q2) -{ +int thole_set_params(int part_type_a, int part_type_b, double scaling_coeff, + double q1q2) { IA_parameters *data = get_ia_param_safe(part_type_a, part_type_b); - - if (!data) return ES_ERROR; + + if (!data) + return ES_ERROR; data->THOLE_scaling_coeff = scaling_coeff; data->THOLE_q1q2 = q1q2; /* broadcast interaction parameters */ mpi_bcast_ia_params(part_type_a, part_type_b); - + return ES_OK; } #endif diff --git a/src/core/thole.hpp b/src/core/thole.hpp index 94617fc11c..a90577d76b 100755 --- a/src/core/thole.hpp +++ b/src/core/thole.hpp @@ -1,27 +1,27 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef _THOLE_H #define _THOLE_H /** \file thole.hpp - * Routines to calculate the thole dampingi energy and/or force + * Routines to calculate the thole dampingi energy and/or force * for a particle pair. * \ref forces.cpp */ @@ -30,67 +30,78 @@ #ifdef THOLE -#include "utils.hpp" #include "debug.hpp" #include "interaction_data.hpp" -#include "particle_data.hpp" #include "p3m.hpp" +#include "particle_data.hpp" +#include "utils.hpp" -int thole_set_params(int part_type_a, int part_type_b, double scaling_coeff, double q1q2); +int thole_set_params(int part_type_a, int part_type_b, double scaling_coeff, + double q1q2); -inline void add_thole_pair_force(const Particle * const p1, const Particle * const p2, IA_parameters *ia_params, - double d[3], double dist, double force[3]) -{ +inline void add_thole_pair_force(const Particle *const p1, + const Particle *const p2, + IA_parameters *ia_params, double d[3], + double dist, double force[3]) { double thole_q1q2 = ia_params->THOLE_q1q2; double thole_s = ia_params->THOLE_scaling_coeff; - if (thole_s != 0 && thole_q1q2 != 0 && dist < p3m.params.r_cut && !(pair_bond_enum_exists_between(p1,p2, BONDED_IA_THERMALIZED_DIST))) { + if (thole_s != 0 && thole_q1q2 != 0 && dist < p3m.params.r_cut && + !(pair_bond_enum_exists_between(p1, p2, BONDED_IA_THERMALIZED_DIST))) { - double dist2 = dist*dist; - - //Subtract p3m shortrange (dipole-dipole charge portion) to add damped coulomb later - p3m_add_pair_force(-thole_q1q2, d, dist2, dist, force); - - //Calc damping function (see doi.org/10.1016/0301-0104(81)85176-2) - // S(r) = 1.0 - (1.0 + thole_s*r/2.0) * exp(-thole_s*r); - // Calc F = - d/dr ( S(r)*q1q2/r) = -(1/2)*(-2+(r^2*s^2+2*r*s+2)*exp(-s*r))*q1q2/r^2 - // Everything before q1q2/r^2 can be used as a factor for the p3m_add_pair_force method - double sr = thole_s * dist; - double dS_r = 0.5 * ( 2.0 - ( exp(-sr) * (sr * (sr + 2.0) + 2.0) ) ); - //Add damped p3m shortrange of dipole term - p3m_add_pair_force(thole_q1q2*dS_r, d, dist2, dist, force); - + double dist2 = dist * dist; - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: THOLE f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist,thole_s)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: THOLE f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist,thole_s)); + // Subtract p3m shortrange (dipole-dipole charge portion) to add damped + // coulomb later + p3m_add_pair_force(-thole_q1q2, d, dist2, dist, force); + // Calc damping function (see doi.org/10.1016/0301-0104(81)85176-2) + // S(r) = 1.0 - (1.0 + thole_s*r/2.0) * exp(-thole_s*r); + // Calc F = - d/dr ( S(r)*q1q2/r) = + // -(1/2)*(-2+(r^2*s^2+2*r*s+2)*exp(-s*r))*q1q2/r^2 + // Everything before q1q2/r^2 can be used as a factor for the + // p3m_add_pair_force method + double sr = thole_s * dist; + double dS_r = 0.5 * (2.0 - (exp(-sr) * (sr * (sr + 2.0) + 2.0))); + // Add damped p3m shortrange of dipole term + p3m_add_pair_force(thole_q1q2 * dS_r, d, dist2, dist, force); + + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: THOLE f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, dist, thole_s)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: THOLE f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, dist, thole_s)); } } +inline double thole_pair_energy(const Particle *p1, const Particle *p2, + const IA_parameters *ia_params, + const double d[3], double dist) { + double e_thole = 0; -inline double thole_pair_energy(const Particle *p1, const Particle *p2, const IA_parameters *ia_params, - const double d[3], double dist) -{ - double e_thole = 0; - - double thole_s = ia_params->THOLE_scaling_coeff; - double thole_q1q2 = ia_params->THOLE_q1q2; - - if (thole_s != 0 && thole_q1q2 != 0 && dist < p3m.params.r_cut && !(pair_bond_enum_exists_between(p1,p2, BONDED_IA_THERMALIZED_DIST))) { + double thole_s = ia_params->THOLE_scaling_coeff; + double thole_q1q2 = ia_params->THOLE_q1q2; - double dist2 = dist*dist; - double chgfac = p1->p.q*p2->p.q; + if (thole_s != 0 && thole_q1q2 != 0 && dist < p3m.params.r_cut && + !(pair_bond_enum_exists_between(p1, p2, BONDED_IA_THERMALIZED_DIST))) { - //Subtract p3m shortrange energy - e_thole += p3m_pair_energy(-chgfac, dist); + double dist2 = dist * dist; + double chgfac = p1->p.q * p2->p.q; - //Add damped p3m shortrange energy - double sd = thole_s*dist; - double S_r = 1.0 - (1.0 + sd/2.0) * exp(-sd); - e_thole += p3m_pair_energy(thole_q1q2*S_r, dist); - } - return e_thole; + // Subtract p3m shortrange energy + e_thole += p3m_pair_energy(-chgfac, dist); + // Add damped p3m shortrange energy + double sd = thole_s * dist; + double S_r = 1.0 - (1.0 + sd / 2.0) * exp(-sd); + e_thole += p3m_pair_energy(thole_q1q2 * S_r, dist); + } + return e_thole; } #endif diff --git a/src/core/tuning.cpp b/src/core/tuning.cpp index 4891985304..5109d72de7 100755 --- a/src/core/tuning.cpp +++ b/src/core/tuning.cpp @@ -1,35 +1,35 @@ /* Copyright (C) 2010,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file tuning.cpp Implementation of tuning.hpp . */ -#include -#include -#include "utils.hpp" #include "communication.hpp" #include "errorhandling.hpp" -#include "integrate.hpp" #include "global.hpp" -#include +#include "integrate.hpp" +#include "utils.hpp" #include "utils/statistics/RunningAverage.hpp" +#include +#include +#include int timing_samples = 10; @@ -41,19 +41,18 @@ int timing_samples = 10; * * @return Time per integration in ms. */ -double time_force_calc(int default_samples) -{ +double time_force_calc(int default_samples) { int rds = timing_samples > 0 ? timing_samples : default_samples; int i; Utils::Statistics::RunningAverage running_average; - + if (mpi_integrate(0, 0)) return -1; /* perform force calculation test */ for (i = 0; i < rds; i++) { const double tick = MPI_Wtime(); - + if (mpi_integrate(0, -1)) return -1; @@ -61,16 +60,16 @@ double time_force_calc(int default_samples) running_average.add_sample((tock - tick)); } - if(running_average.avg() <= 5*MPI_Wtick()) { + if (running_average.avg() <= 5 * MPI_Wtick()) { runtimeWarning("Clock resolution is to low to reliably time integration."); } - if(running_average.sig() >= 0.1*running_average.avg()) { + if (running_average.sig() >= 0.1 * running_average.avg()) { runtimeWarning("Statistics of tuning samples is very bad."); } /* MPI returns s, return value should be in ms. */ - return 1000.*running_average.avg(); + return 1000. * running_average.avg(); } /** @@ -81,19 +80,18 @@ double time_force_calc(int default_samples) * @param rds Number of steps to integrate. * @return Time per integration in ms. */ -static double time_calc(int rds) -{ +static double time_calc(int rds) { if (mpi_integrate(0, 0)) return -1; /* perform force calculation test */ const double tick = MPI_Wtime(); - if (mpi_integrate(rds, -1)) - return -1; + if (mpi_integrate(rds, -1)) + return -1; const double tock = MPI_Wtime(); /* MPI returns s, return value should be in ms. */ - return 1000.*(tock - tick)/rds; + return 1000. * (tock - tick) / rds; } void tune_skin(double min, double max, double tol, int steps) { @@ -103,21 +101,21 @@ void tune_skin(double min, double max, double tol, int steps) { double b = max; double time_a, time_b; - while(fabs(a - b) > tol) { + while (fabs(a - b) > tol) { skin = a; - mpi_bcast_parameter(FIELD_SKIN); + mpi_bcast_parameter(FIELD_SKIN); time_a = time_calc(steps); skin = b; - mpi_bcast_parameter(FIELD_SKIN); + mpi_bcast_parameter(FIELD_SKIN); time_b = time_calc(steps); - if(time_a > time_b) { - a = 0.5*(a + b); + if (time_a > time_b) { + a = 0.5 * (a + b); } else { - b = 0.5*(a + b); + b = 0.5 * (a + b); } } - skin = 0.5*(a+b); - mpi_bcast_parameter(FIELD_SKIN); + skin = 0.5 * (a + b); + mpi_bcast_parameter(FIELD_SKIN); } diff --git a/src/core/umbrella.cpp b/src/core/umbrella.cpp index 43cc54be17..eb1b68a86e 100644 --- a/src/core/umbrella.cpp +++ b/src/core/umbrella.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2010,2011,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file umbrella.cpp * @@ -27,10 +27,8 @@ #ifdef UMBRELLA -int umbrella_set_params(int bond_type, double k, - int dir, double r) -{ - if(bond_type < 0) +int umbrella_set_params(int bond_type, double k, int dir, double r) { + if (bond_type < 0) return ES_ERROR; make_bond_type_exist(bond_type); @@ -39,14 +37,12 @@ int umbrella_set_params(int bond_type, double k, bonded_ia_params[bond_type].p.umbrella.dir = dir; bonded_ia_params[bond_type].p.umbrella.r = r; bonded_ia_params[bond_type].type = BONDED_IA_UMBRELLA; - bonded_ia_params[bond_type].num = 1; + bonded_ia_params[bond_type].num = 1; /* broadcast interaction parameters */ mpi_bcast_ia_params(bond_type, -1); return ES_OK; - } #endif /* ifdef UMBRELLA */ - diff --git a/src/core/umbrella.hpp b/src/core/umbrella.hpp index 33413df9a1..3bdb085220 100644 --- a/src/core/umbrella.hpp +++ b/src/core/umbrella.hpp @@ -1,74 +1,78 @@ /* Copyright (C) 2010,2012,2013,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #ifndef umbrella_H #define umbrella_H /** \file umbrella.hpp - * Routines to calculate the umbrella energy and/or force - * for a particle pair: harmonic interaction in only one + * Routines to calculate the umbrella energy and/or force + * for a particle pair: harmonic interaction in only one * cartesian direction. Useful for umbrella sampling simulations. * \ref forces.cpp */ -#include "utils.hpp" #include "interaction_data.hpp" #include "particle_data.hpp" +#include "utils.hpp" #ifdef UMBRELLA /// -int umbrella_set_params(int bond_type, double k, - int dir, double r); - +int umbrella_set_params(int bond_type, double k, int dir, double r); /** Resultant Force due to an umbrella potential */ -inline double umbrella_force_r(double k, int dir, double r, double distn ) -{ +inline double umbrella_force_r(double k, int dir, double r, double distn) { return -k * (distn - r); } /** Calculate umbrella potential force between particle p1 and p2 */ -inline int calc_umbrella_pair_force(Particle *p1, Particle *p2, Bonded_ia_parameters *ia_params, - double d[3], double force[3]) -{ +inline int calc_umbrella_pair_force(Particle *p1, Particle *p2, + Bonded_ia_parameters *ia_params, + double d[3], double force[3]) { double distn; - double fac=0.0; + double fac = 0.0; distn = d[ia_params->p.umbrella.dir]; fac = -ia_params->p.umbrella.k * (distn - ia_params->p.umbrella.r); force[ia_params->p.umbrella.dir] += fac; - - ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr, - "%d: OPT: umbrella f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,distn,fac)); - ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr, - "%d: OPT: umbrella f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,distn,fac)); + + ONEPART_TRACE(if (p1->p.identity == check_id) + fprintf(stderr, "%d: OPT: umbrella f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p1->f.f[0], p1->f.f[1], p1->f.f[2], + p2->p.identity, distn, fac)); + ONEPART_TRACE(if (p2->p.identity == check_id) + fprintf(stderr, "%d: OPT: umbrella f = (%.3e,%.3e,%.3e) " + "with part id=%d at dist %f fac %.3e\n", + this_node, p2->f.f[0], p2->f.f[1], p2->f.f[2], + p1->p.identity, distn, fac)); return 0; } /** calculate umbrella energy between particle p1 and p2. */ -inline int umbrella_pair_energy(Particle *p1, Particle *p2, Bonded_ia_parameters *ia_params, - double d[3], double *_energy) -{ +inline int umbrella_pair_energy(Particle *p1, Particle *p2, + Bonded_ia_parameters *ia_params, double d[3], + double *_energy) { double distn; - distn = d[ia_params->p.umbrella.dir]; - *_energy = 0.5 * ia_params->p.umbrella.k * Utils::sqr(distn - ia_params->p.umbrella.r); + distn = d[ia_params->p.umbrella.dir]; + *_energy = 0.5 * ia_params->p.umbrella.k * + Utils::sqr(distn - ia_params->p.umbrella.r); return 0; } diff --git a/src/core/unit_tests/Batch_test.cpp b/src/core/unit_tests/Batch_test.cpp index fc8d992df6..d3a09e7a26 100644 --- a/src/core/unit_tests/Batch_test.cpp +++ b/src/core/unit_tests/Batch_test.cpp @@ -30,22 +30,21 @@ BOOST_AUTO_TEST_CASE(batch) { int counter = 0; - auto a = [&counter] (int i) { - BOOST_CHECK(i == 42); - BOOST_CHECK(counter++ == 0); - }; - auto b = [&counter] (int i) { - BOOST_CHECK(i == 42); - BOOST_CHECK(counter++ == 1); - }; - auto c = [&counter] (int i) { - BOOST_CHECK(i == 42); - BOOST_CHECK(counter++ == 2); - }; + auto a = [&counter](int i) { + BOOST_CHECK(i == 42); + BOOST_CHECK(counter++ == 0); + }; + auto b = [&counter](int i) { + BOOST_CHECK(i == 42); + BOOST_CHECK(counter++ == 1); + }; + auto c = [&counter](int i) { + BOOST_CHECK(i == 42); + BOOST_CHECK(counter++ == 2); + }; auto batch = Utils::make_batch(a, b, c); batch(42); BOOST_CHECK(counter == 3); } - diff --git a/src/core/unit_tests/Cache_test.cpp b/src/core/unit_tests/Cache_test.cpp index 63680b55c1..0c8b555d34 100644 --- a/src/core/unit_tests/Cache_test.cpp +++ b/src/core/unit_tests/Cache_test.cpp @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(get_value) { BOOST_AUTO_TEST_CASE(has) { { Cache cache; - cache.put(41,0); + cache.put(41, 0); cache.put(1, 0); BOOST_CHECK(cache.has(41)); @@ -85,18 +85,18 @@ BOOST_AUTO_TEST_CASE(put) { BOOST_AUTO_TEST_CASE(max_size) { { - Cache cache(1); + Cache cache(1); - cache.put(1, 2); - cache.put(2, 3); + cache.put(1, 2); + cache.put(2, 3); - BOOST_CHECK(!cache.has(1)); - BOOST_CHECK(cache.has(2)); + BOOST_CHECK(!cache.has(1)); + BOOST_CHECK(cache.has(2)); - cache.put(1, 2); + cache.put(1, 2); - BOOST_CHECK(cache.has(1)); - BOOST_CHECK(!cache.has(2)); + BOOST_CHECK(cache.has(1)); + BOOST_CHECK(!cache.has(2)); } { @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(max_size) { const Cache::size_type max_size = 1000; Cache cache(max_size); - for(int i = 0; i < 10000; i++) { + for (int i = 0; i < 10000; i++) { cache.put(i, 11); } @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(range_put) { std::vector keys = {1, 2, 3, 4, 5}; std::vector vals = {6, 7, 8, 9, 10}; - for(int i = 12; i > 0; i--) + for (int i = 12; i > 0; i--) cache.put(i, i); cache.put(keys.begin(), keys.end(), vals.begin()); diff --git a/src/core/unit_tests/Factory_test.cpp b/src/core/unit_tests/Factory_test.cpp index d1481083af..7fe00b29b6 100644 --- a/src/core/unit_tests/Factory_test.cpp +++ b/src/core/unit_tests/Factory_test.cpp @@ -1,20 +1,20 @@ /* Copyright (C) 2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /** \file Factory_test.cpp Unit tests for the Utils::Factory class. @@ -50,15 +50,19 @@ BOOST_AUTO_TEST_CASE(regiser_class) { typedef Utils::Factory Factory; /* Overload with explicit builder */ - Factory::register_new("test_class", Utils::Factory::builder); - Utils::Factory::register_new("derived_test_class", Utils::Factory::builder); + Factory::register_new("test_class", + Utils::Factory::builder); + Utils::Factory::register_new( + "derived_test_class", + Utils::Factory::builder); /* Overload with default builder */ - Utils::Factory::register_new("other_derived_class"); + Utils::Factory::register_new( + "other_derived_class"); /* All three builders should be present. */ BOOST_CHECK(Factory::has_builder("test_class")); BOOST_CHECK(Factory::has_builder("derived_test_class")); - BOOST_CHECK(Factory::has_builder("other_derived_class")); + BOOST_CHECK(Factory::has_builder("other_derived_class")); } /** Check object construction. */ @@ -73,5 +77,5 @@ BOOST_AUTO_TEST_CASE(make) { BOOST_CHECK(o != nullptr); /* Check for correct (derived) type */ - BOOST_CHECK(dynamic_cast(o.get()) != nullptr); + BOOST_CHECK(dynamic_cast(o.get()) != nullptr); } diff --git a/src/core/unit_tests/ParticleCache_test.cpp b/src/core/unit_tests/ParticleCache_test.cpp index 279d33f308..28dc9acd71 100644 --- a/src/core/unit_tests/ParticleCache_test.cpp +++ b/src/core/unit_tests/ParticleCache_test.cpp @@ -36,8 +36,8 @@ #define BOOST_TEST_DYN_LINK #include -#include "utils/List.hpp" #include "mock/Particle.hpp" +#include "utils/List.hpp" using Communication::MpiCallbacks; namespace mpi = boost::mpi; diff --git a/src/core/unit_tests/ParticleIterator_test.cpp b/src/core/unit_tests/ParticleIterator_test.cpp index 41a20b985e..ae84bedc18 100644 --- a/src/core/unit_tests/ParticleIterator_test.cpp +++ b/src/core/unit_tests/ParticleIterator_test.cpp @@ -1,7 +1,7 @@ #include +#include #include #include -#include #include "core/utils/make_unique.hpp" diff --git a/src/core/unit_tests/RunningAverage_test.cpp b/src/core/unit_tests/RunningAverage_test.cpp index 7b9a807bfa..0447204a15 100644 --- a/src/core/unit_tests/RunningAverage_test.cpp +++ b/src/core/unit_tests/RunningAverage_test.cpp @@ -1,27 +1,27 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Max-Planck-Institute for Polymer Research, Theory Group - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ +#include #include #include -#include #include #define BOOST_TEST_MODULE RunningAverage test @@ -67,37 +67,41 @@ BOOST_AUTO_TEST_CASE(simple_variance_check) { avg.add_sample(0.0); avg.add_sample(5.0); - /** Var should be - **2 = (0**2 + 5.0**2) / 2. - 2.5**2 = 12.5 - 6.25 = 6.25 */ - BOOST_CHECK(std::fabs(avg.avg() - 2.5) <= std::numeric_limits::epsilon()); - BOOST_CHECK(std::fabs(avg.var() - 6.25) <= std::numeric_limits::epsilon()); + /** Var should be - **2 = (0**2 + 5.0**2) / 2. - 2.5**2 = 12.5 - + * 6.25 = 6.25 */ + BOOST_CHECK(std::fabs(avg.avg() - 2.5) <= + std::numeric_limits::epsilon()); + BOOST_CHECK(std::fabs(avg.var() - 6.25) <= + std::numeric_limits::epsilon()); /** Standard deviation should be sqrt(var()) */ - BOOST_CHECK(std::fabs(avg.sig() - std::sqrt(avg.var())) <= std::numeric_limits::epsilon()); + BOOST_CHECK(std::fabs(avg.sig() - std::sqrt(avg.var())) <= + std::numeric_limits::epsilon()); } BOOST_AUTO_TEST_CASE(mean_and_variance) { Utils::Statistics::RunningAverage running_average; const size_t sample_size = sizeof(RandomSequence::values) / sizeof(double); - for(auto const& val: RandomSequence::values) { + for (auto const &val : RandomSequence::values) { running_average.add_sample(val); } - BOOST_CHECK(running_average.n() == sample_size); - + BOOST_CHECK(running_average.n() == sample_size); + /** Directly calculate the meann from the data */ const double m_mean = std::accumulate(std::begin(RandomSequence::values), - std::end(RandomSequence::values), - 0.0) / sample_size; + std::end(RandomSequence::values), 0.0) / + sample_size; BOOST_CHECK(std::fabs(running_average.avg() - m_mean) <= 1e-12); /** Directly calculate the variance from the data */ double m_var = 0.0; - for(auto const& val: RandomSequence::values) { - m_var += (val - m_mean)*(val - m_mean); + for (auto const &val : RandomSequence::values) { + m_var += (val - m_mean) * (val - m_mean); } m_var /= sample_size; - BOOST_CHECK(std::fabs(running_average.var() - m_var) <= 1e-12); + BOOST_CHECK(std::fabs(running_average.var() - m_var) <= 1e-12); } diff --git a/src/core/unit_tests/RuntimeError_test.cpp b/src/core/unit_tests/RuntimeError_test.cpp index 671cecc8df..41eef09f34 100644 --- a/src/core/unit_tests/RuntimeError_test.cpp +++ b/src/core/unit_tests/RuntimeError_test.cpp @@ -68,7 +68,8 @@ BOOST_AUTO_TEST_CASE(def_ctor_and_assignment) { RuntimeError err(level, who, what, function, file, line); /** Copy ctor */ - RuntimeError err2(err); // NOLINT (local copy 'err2' of the variable 'err' is never modified; consider avoiding the copy) + RuntimeError err2(err); // NOLINT (local copy 'err2' of the variable 'err' is + // never modified; consider avoiding the copy) BOOST_CHECK(level == err2.level()); BOOST_CHECK(what == err2.what()); diff --git a/src/core/unit_tests/SkipIterator_test.cpp b/src/core/unit_tests/SkipIterator_test.cpp index 7a9d1e41fe..aa63db7f5a 100644 --- a/src/core/unit_tests/SkipIterator_test.cpp +++ b/src/core/unit_tests/SkipIterator_test.cpp @@ -1,7 +1,7 @@ #include -#include #include #include +#include #define BOOST_TEST_MODULE SkipIterator test #define BOOST_TEST_DYN_LINK @@ -11,7 +11,7 @@ BOOST_AUTO_TEST_CASE(skip) { using Utils::make_skip_iterator; - + std::vector data(50); std::iota(data.begin(), data.end(), 1); @@ -20,14 +20,14 @@ BOOST_AUTO_TEST_CASE(skip) { auto begin = make_skip_iterator(data.begin(), data.end(), multiple_of_3); auto end = make_skip_iterator(data.end(), data.end(), multiple_of_3); - for(; begin != end; ++begin) { + for (; begin != end; ++begin) { BOOST_CHECK(!multiple_of_3(*begin)); } } BOOST_AUTO_TEST_CASE(empty) { using Utils::make_skip_iterator; - + std::vector data(50); std::iota(data.begin(), data.end(), 1); @@ -41,12 +41,12 @@ BOOST_AUTO_TEST_CASE(empty) { BOOST_AUTO_TEST_CASE(gap) { using Utils::make_skip_iterator; - + std::vector values; - for(int i = 1; i <= 10; i++) { + for (int i = 1; i <= 10; i++) { values.push_back(i); - for(int j = 0; j < i; j++) { + for (int j = 0; j < i; j++) { values.push_back(0); } } diff --git a/src/core/unit_tests/Span_test.cpp b/src/core/unit_tests/Span_test.cpp index 34f4f018cf..55b599d519 100644 --- a/src/core/unit_tests/Span_test.cpp +++ b/src/core/unit_tests/Span_test.cpp @@ -24,8 +24,8 @@ #include "utils/Span.hpp" using Utils::Span; -#include #include +#include BOOST_AUTO_TEST_CASE(const_expr_ctor) { static_assert(4 == Span(nullptr, 4).size(), ""); @@ -33,12 +33,10 @@ BOOST_AUTO_TEST_CASE(const_expr_ctor) { BOOST_AUTO_TEST_CASE(array_ctor) { BOOST_CHECK((std::is_constructible, int[3]>::value)); - BOOST_CHECK( - (std::is_constructible, const int[3]>::value)); - BOOST_CHECK(not (std::is_constructible, const int[3]>::value)); + BOOST_CHECK((std::is_constructible, const int[3]>::value)); + BOOST_CHECK(not(std::is_constructible, const int[3]>::value)); BOOST_CHECK((std::is_convertible>::value)); - BOOST_CHECK( - (std::is_convertible>::value)); + BOOST_CHECK((std::is_convertible>::value)); int a[4] = {1, 2, 3, 4}; Span s(a); @@ -50,23 +48,26 @@ BOOST_AUTO_TEST_CASE(array_ctor) { BOOST_AUTO_TEST_CASE(ctor) { /* Container conversion rules */ { - BOOST_CHECK((std::is_constructible, std::vector>::value)); BOOST_CHECK( - (std::is_constructible, const std::vector>::value)); - BOOST_CHECK(not(std::is_constructible, const std::vector>::value)); - BOOST_CHECK((std::is_convertible, Span>::value)); + (std::is_constructible, std::vector>::value)); + BOOST_CHECK(( + std::is_constructible, const std::vector>::value)); + BOOST_CHECK( + not(std::is_constructible, const std::vector>::value)); BOOST_CHECK( - (std::is_convertible, Span>::value)); + (std::is_convertible, Span>::value)); + BOOST_CHECK( + (std::is_convertible, Span>::value)); } /* from ptr + size */ { - std::vector v(23); + std::vector v(23); - auto s = Span(v.data(), v.size()); + auto s = Span(v.data(), v.size()); - BOOST_CHECK(v.size() == s.size()); - BOOST_CHECK(v.data() == s.data()); + BOOST_CHECK(v.size() == s.size()); + BOOST_CHECK(v.data() == s.data()); } /* From container */ @@ -77,7 +78,6 @@ BOOST_AUTO_TEST_CASE(ctor) { BOOST_CHECK(v.size() == s.size()); BOOST_CHECK(v.data() == s.data()); } - } BOOST_AUTO_TEST_CASE(iterators) { @@ -106,4 +106,3 @@ BOOST_AUTO_TEST_CASE(element_access) { BOOST_CHECK_THROW(s.at(s.size()), std::out_of_range); } - diff --git a/src/core/unit_tests/Variant_test.cpp b/src/core/unit_tests/Variant_test.cpp index 71fab21c1e..122cb395e3 100644 --- a/src/core/unit_tests/Variant_test.cpp +++ b/src/core/unit_tests/Variant_test.cpp @@ -194,7 +194,10 @@ BOOST_AUTO_TEST_CASE(make_shared_from_args_test) { BOOST_AUTO_TEST_CASE(call_with_args_test) { struct C { - int mem(std::string s) { s.clear(); return 12; } + int mem(std::string s) { + s.clear(); + return 12; + } }; VariantMap vals{{"s", std::string()}}; diff --git a/src/core/unit_tests/accumulator.cpp b/src/core/unit_tests/accumulator.cpp index 81f342bc41..195d12c0c0 100644 --- a/src/core/unit_tests/accumulator.cpp +++ b/src/core/unit_tests/accumulator.cpp @@ -10,9 +10,13 @@ BOOST_AUTO_TEST_CASE(accumulator) { auto test_data2 = std::vector{{1.5, 3.5, 3.5, 4.5}}; acc(test_data1); BOOST_CHECK(acc.get_mean() == test_data1); - BOOST_CHECK(acc.get_variance() == std::vector(4, std::numeric_limits::max())); + BOOST_CHECK(acc.get_variance() == + std::vector(4, std::numeric_limits::max())); acc(test_data2); - BOOST_CHECK((acc.get_mean() == std::vector{{0.75, 2.25, 2.75, 3.75}})); - BOOST_CHECK((acc.get_variance() == std::vector{{1.125, 3.125, 1.125, 1.125}})); - BOOST_CHECK((acc.get_std_error() == std::vector{{0.75, 1.25, 0.75, 0.75}})); + BOOST_CHECK( + (acc.get_mean() == std::vector{{0.75, 2.25, 2.75, 3.75}})); + BOOST_CHECK((acc.get_variance() == + std::vector{{1.125, 3.125, 1.125, 1.125}})); + BOOST_CHECK( + (acc.get_std_error() == std::vector{{0.75, 1.25, 0.75, 0.75}})); } diff --git a/src/core/unit_tests/for_each_pair_test.cpp b/src/core/unit_tests/for_each_pair_test.cpp index 3b513e51fd..56b9d6c5fe 100644 --- a/src/core/unit_tests/for_each_pair_test.cpp +++ b/src/core/unit_tests/for_each_pair_test.cpp @@ -47,7 +47,7 @@ void check_pairs(int n_values, std::vector> &pairs) { BOOST_AUTO_TEST_CASE(basic_check) { auto const n_values = 141; std::vector vec(n_values); - + std::iota(vec.begin(), vec.end(), 0); std::vector> pairs; diff --git a/src/core/unit_tests/gather_buffer_test.cpp b/src/core/unit_tests/gather_buffer_test.cpp index 9bff2a657b..9edefa221d 100644 --- a/src/core/unit_tests/gather_buffer_test.cpp +++ b/src/core/unit_tests/gather_buffer_test.cpp @@ -34,7 +34,7 @@ using Utils::Mpi::gather_buffer; namespace mpi = boost::mpi; -void check_pointer(const mpi::communicator & comm, int root) { +void check_pointer(const mpi::communicator &comm, int root) { if (comm.rank() == root) { auto const n = comm.size(); const int total_size = n * (n + 1) / 2; @@ -67,7 +67,7 @@ void check_pointer(const mpi::communicator & comm, int root) { } } -void check_vector(const mpi::communicator & comm, int root) { +void check_vector(const mpi::communicator &comm, int root) { std::vector buf(comm.rank() + 1, comm.rank() + 1); gather_buffer(buf, comm, root); @@ -97,7 +97,7 @@ void check_vector(const mpi::communicator & comm, int root) { } } -void check_vector_empty(const mpi::communicator & comm, int empty) { +void check_vector_empty(const mpi::communicator &comm, int empty) { std::vector buf((comm.rank() == empty) ? 0 : 11, comm.rank()); gather_buffer(buf, comm); @@ -117,7 +117,7 @@ void check_vector_empty(const mpi::communicator & comm, int empty) { } } -void check_pointer_empty(const mpi::communicator & comm, int empty) { +void check_pointer_empty(const mpi::communicator &comm, int empty) { auto const n_elem = (comm.rank() == empty) ? 0 : 11; std::vector buf(n_elem, comm.rank()); @@ -202,11 +202,11 @@ BOOST_AUTO_TEST_CASE(non_trivial_type) { gather_buffer(buf, world); - if(world.rank() == 0) { + if (world.rank() == 0) { auto const n = world.size(); - BOOST_CHECK(buf.size() == (n * (n+1) / 2)); + BOOST_CHECK(buf.size() == (n * (n + 1) / 2)); - for(auto const& e : buf) { + for (auto const &e : buf) { BOOST_CHECK(e == s); } } diff --git a/src/core/unit_tests/get_value_test.cpp b/src/core/unit_tests/get_value_test.cpp index 3f1b55de52..b781eb8923 100644 --- a/src/core/unit_tests/get_value_test.cpp +++ b/src/core/unit_tests/get_value_test.cpp @@ -46,8 +46,8 @@ BOOST_AUTO_TEST_CASE(empty_vector) { // NOLINT using ScriptInterface::get_value; using ScriptInterface::Variant; - Variant v = std::vector{}; // NOLINT - auto vec = get_value>(v); //NOLINT + Variant v = std::vector{}; // NOLINT + auto vec = get_value>(v); // NOLINT BOOST_CHECK(std::vector{} == vec); } diff --git a/src/core/unit_tests/histogram.cpp b/src/core/unit_tests/histogram.cpp index 7789c2ead9..e3b519f3ac 100644 --- a/src/core/unit_tests/histogram.cpp +++ b/src/core/unit_tests/histogram.cpp @@ -14,8 +14,8 @@ BOOST_AUTO_TEST_CASE(histogram) { // Check getters. BOOST_CHECK(hist.get_limits() == limits); BOOST_CHECK(hist.get_n_bins() == n_bins); - BOOST_CHECK( - (hist.get_bin_sizes() == std::array{{19.0 / 10.0, 5.0 / 10.0}})); + BOOST_CHECK((hist.get_bin_sizes() == + std::array{{19.0 / 10.0, 5.0 / 10.0}})); // Check that histogram is initialized to zero. BOOST_CHECK(hist.get_histogram() == std::vector(n_dims_data * n_bins[0] * n_bins[1], 0.0)); diff --git a/src/core/unit_tests/keys_test.cpp b/src/core/unit_tests/keys_test.cpp index 9de7b0091e..09c8ef144a 100644 --- a/src/core/unit_tests/keys_test.cpp +++ b/src/core/unit_tests/keys_test.cpp @@ -27,7 +27,7 @@ #include BOOST_AUTO_TEST_CASE(values) { - using pair_type = std::map::value_type; + using pair_type = std::map::value_type; auto pairs = std::map{{31, 2}, {2, 63}, {23, 9}, {4, 9}}; auto keys = Utils::keys(pairs); @@ -36,4 +36,3 @@ BOOST_AUTO_TEST_CASE(values) { std::equal(keys.begin(), keys.end(), pairs.begin(), [](int k, pair_type const &kv) { return k == kv.first; })); } - diff --git a/src/core/unit_tests/mock/Cell.hpp b/src/core/unit_tests/mock/Cell.hpp index f2845429b0..1ac7179259 100644 --- a/src/core/unit_tests/mock/Cell.hpp +++ b/src/core/unit_tests/mock/Cell.hpp @@ -1,8 +1,8 @@ #ifndef CORE_UNIT_TESTS_MOCK_CELL_HPP #define CORE_UNIT_TESTS_MOCK_CELL_HPP -#include #include +#include namespace Testing { template class Cell { diff --git a/src/core/unit_tests/mock/CellPList.hpp b/src/core/unit_tests/mock/CellPList.hpp index b209b9eb73..303bff63d5 100644 --- a/src/core/unit_tests/mock/CellPList.hpp +++ b/src/core/unit_tests/mock/CellPList.hpp @@ -2,9 +2,7 @@ #define TESTING_CELL_P_LIST_HPP namespace Testing { - class CellPList { - - }; +class CellPList {}; } #endif diff --git a/src/core/unit_tests/random_sequence.hpp b/src/core/unit_tests/random_sequence.hpp index 509e290389..ebbe5910d7 100644 --- a/src/core/unit_tests/random_sequence.hpp +++ b/src/core/unit_tests/random_sequence.hpp @@ -1,2503 +1,2506 @@ -namespace Testing { namespace RandomSequence { +namespace Testing { +namespace RandomSequence { -static const double values[] = { 5.36812441e-01, 9.05016283e-01, 2.21117887e-01, 5.02819496e-01, - 7.63086501e-01, 6.53893270e-01, 8.23665727e-01, 9.69872102e-01, - 3.40061134e-01, 1.51051652e-01, 1.90729935e-01, 3.95479722e-01, - 8.75884366e-01, 7.05225909e-01, 9.67985410e-01, 9.67231568e-01, - 3.16638187e-01, 2.07409147e-01, 8.73259933e-01, 6.43942066e-01, - 1.78484038e-02, 7.12456953e-01, 8.86710346e-01, 9.38996311e-01, - 3.35287423e-01, 8.90043645e-01, 9.34030467e-01, 5.15824085e-01, - 6.23115364e-02, 1.16789345e-01, 8.50941823e-01, 1.67876163e-01, - 1.31041168e-01, 9.93168994e-02, 1.41431817e-01, 8.90690809e-01, - 2.02488098e-01, 7.36300956e-01, 1.55234556e-02, 2.20287030e-01, - 9.36321073e-01, 1.28409939e-01, 3.08036214e-01, 8.67956164e-02, - 1.11136507e-01, 9.60890548e-01, 9.88958063e-01, 9.53397532e-01, - 5.79151680e-01, 7.23213235e-01, 2.27149695e-01, 7.58832055e-01, - 1.12813268e-01, 8.35874616e-01, 1.89134687e-01, 5.12455825e-01, - 4.25818943e-02, 3.11057974e-01, 5.20592461e-01, 4.14944838e-01, - 7.62577185e-01, 8.77537698e-02, 3.77975887e-01, 1.07129081e-01, - 2.80648306e-01, 1.57044211e-01, 9.24362351e-01, 9.60771393e-01, - 2.30143289e-01, 9.80732668e-01, 4.22272940e-01, 2.44685865e-01, - 9.95728448e-01, 7.03337832e-01, 9.43639937e-01, 4.10483955e-01, - 5.49454891e-01, 2.73267928e-02, 7.54862939e-01, 4.10246593e-02, - 6.72925227e-01, 8.45630228e-01, 8.24185778e-01, 5.86034357e-01, - 2.45186711e-01, 1.46556640e-02, 7.83866884e-01, 3.27409940e-01, - 1.87732538e-01, 3.08269456e-01, 9.41082410e-01, 8.60992214e-01, - 4.29335830e-01, 7.30630195e-01, 2.26017436e-01, 5.64492936e-01, - 7.53212812e-02, 5.46318587e-01, 2.06760814e-01, 8.63181719e-01, - 5.14394315e-01, 6.09138749e-01, 4.18657254e-01, 5.91929447e-01, - 8.92082831e-01, 2.19417367e-01, 4.77365478e-02, 7.26974646e-01, - 3.90718957e-01, 5.60553601e-01, 8.68079340e-01, 6.66149233e-01, - 5.65605279e-01, 4.17322107e-01, 3.58916838e-02, 3.20056919e-01, - 4.69409876e-01, 4.59560328e-01, 3.78865664e-01, 4.70873097e-01, - 6.33834299e-01, 3.56360349e-02, 4.72834116e-01, 5.98245954e-01, - 6.71737750e-01, 3.24785236e-01, 4.72058687e-01, 8.73592505e-01, - 8.17040665e-01, 5.24633123e-01, 1.19966059e-01, 3.31976138e-01, - 9.46976980e-01, 9.33750854e-01, 4.55336961e-01, 3.99956066e-03, - 4.60555081e-01, 2.75436730e-02, 4.45222636e-01, 3.81840487e-01, - 6.90430349e-01, 4.69071563e-01, 8.79427375e-02, 5.51342939e-01, - 5.59734456e-02, 2.75721390e-01, 7.01775098e-01, 1.85279466e-01, - 7.87023428e-01, 8.65878578e-01, 3.46338346e-01, 1.98827346e-01, - 4.62406412e-01, 9.36147813e-01, 6.73068785e-01, 8.21165652e-01, - 3.84137201e-01, 5.54849070e-01, 5.25338471e-01, 4.92960187e-01, - 1.98987654e-01, 4.40366612e-01, 4.91615585e-01, 6.59636951e-01, - 6.56862278e-01, 9.91108369e-01, 2.64080613e-02, 1.59392509e-01, - 1.59326848e-01, 9.80768641e-01, 7.23541978e-01, 6.24664106e-02, - 5.23245400e-01, 8.29540568e-01, 3.79595827e-01, 2.51490705e-01, - 9.03211923e-01, 5.85036337e-01, 2.13804243e-02, 7.02601545e-01, - 8.84451972e-01, 7.44386759e-01, 4.07704650e-01, 8.76135540e-01, - 8.62283593e-02, 8.12646966e-01, 1.99860200e-03, 9.81822688e-01, - 3.98059813e-01, 7.07509226e-01, 3.29087549e-01, 1.49488172e-01, - 9.28632230e-01, 8.67940978e-01, 7.57588079e-01, 2.41147841e-02, - 1.16906710e-01, 9.01610642e-01, 6.48063108e-01, 1.38901827e-01, - 3.69400192e-01, 1.70098717e-02, 6.86210800e-01, 5.19651542e-01, - 9.95125346e-01, 8.59978505e-01, 7.77940487e-01, 7.00603844e-01, - 7.64288441e-01, 7.71847112e-01, 7.68801253e-01, 5.62508922e-01, - 2.78507048e-01, 9.00805306e-02, 5.41263065e-01, 3.91795734e-01, - 7.01280661e-01, 8.76551939e-01, 2.44363950e-01, 7.91509644e-01, - 6.90857642e-01, 7.63697059e-01, 6.45428558e-01, 6.82167839e-01, - 8.33239992e-01, 7.63494477e-01, 9.41177879e-01, 2.56919197e-02, - 1.95005612e-01, 2.17610152e-01, 4.10317359e-01, 7.49023537e-01, - 8.67374419e-02, 8.33918551e-01, 2.89078914e-01, 5.54389435e-01, - 7.79647807e-01, 2.67859885e-01, 3.22589228e-01, 5.73316233e-01, - 2.52832617e-01, 8.35869300e-01, 3.30812610e-01, 9.55867629e-01, - 2.28908323e-01, 9.93198329e-01, 3.98123397e-01, 8.99333947e-01, - 3.82249010e-01, 7.97028510e-01, 7.05980223e-01, 7.93472013e-01, - 8.15960458e-01, 7.50921468e-01, 6.87093503e-01, 6.84088372e-01, - 6.92497398e-01, 3.96633688e-01, 4.13013887e-01, 2.28475282e-01, - 4.60155416e-01, 3.46243470e-01, 7.20709879e-01, 2.94614335e-01, - 6.62684881e-01, 1.36982656e-02, 3.82961800e-01, 8.04081364e-01, - 5.40473423e-01, 3.14540500e-01, 6.23210130e-01, 6.82965861e-01, - 6.31577863e-01, 1.84412937e-01, 8.04611334e-01, 2.25748741e-01, - 9.47193866e-01, 7.36543339e-01, 2.56602607e-02, 8.51909736e-02, - 9.88778351e-01, 1.49808112e-01, 3.91534041e-01, 9.13229877e-01, - 1.81587719e-01, 7.99617499e-01, 4.48458315e-01, 8.57410766e-01, - 7.84580475e-01, 2.68411587e-01, 6.90255704e-01, 1.04220834e-01, - 8.35958260e-01, 6.58782564e-01, 4.78765310e-01, 7.81194957e-01, - 5.99885434e-01, 8.09630883e-01, 1.04707323e-01, 4.72111341e-01, - 9.41931033e-01, 5.04752488e-01, 5.78791731e-01, 2.97554626e-01, - 4.01089318e-01, 2.49185489e-01, 3.85964501e-01, 6.60440483e-01, - 7.73563635e-02, 5.97169647e-01, 7.50404109e-01, 8.85433745e-01, - 1.18036176e-01, 3.36861628e-01, 9.16758521e-01, 4.10648405e-01, - 6.55235522e-01, 3.34384242e-01, 3.88493234e-01, 4.20717897e-01, - 5.28649522e-02, 7.60592922e-01, 6.17367275e-01, 2.34571785e-01, - 5.15619540e-01, 5.81380856e-01, 6.70578777e-01, 4.31113333e-01, - 1.56436542e-01, 6.98107974e-01, 2.76652979e-01, 6.97987014e-01, - 2.98738915e-01, 8.22720683e-01, 9.24549465e-02, 3.78968100e-01, - 1.28890640e-01, 4.12131016e-04, 9.34899694e-01, 9.73355458e-01, - 7.60564472e-01, 9.02434830e-01, 3.75690070e-01, 9.52636429e-01, - 2.91106624e-01, 4.23821343e-01, 1.30204911e-01, 2.72353454e-01, - 2.41791015e-01, 6.55615660e-01, 2.62696179e-01, 9.45745111e-01, - 7.95702851e-01, 6.93790316e-01, 5.57819907e-01, 3.19620135e-01, - 9.11573270e-01, 5.27465702e-01, 9.51558175e-01, 2.95387619e-01, - 6.84395148e-01, 8.49952813e-01, 3.26668856e-01, 9.78348880e-01, - 9.19534607e-02, 2.42212135e-01, 5.32824662e-01, 7.17067053e-02, - 4.71115746e-01, 7.70158064e-01, 8.47999498e-01, 4.20158937e-01, - 4.55412652e-01, 7.19081870e-01, 1.38691180e-01, 8.68676168e-02, - 1.51498147e-02, 5.68162660e-01, 8.72790465e-02, 1.31312082e-01, - 9.79495283e-01, 6.75099064e-01, 2.24999849e-01, 9.76569106e-01, - 7.67219663e-01, 4.37956888e-01, 1.65439333e-01, 9.41914179e-01, - 6.65583742e-01, 9.27526495e-01, 2.37504549e-01, 6.20414894e-01, - 7.77084421e-01, 5.58427639e-01, 1.94030841e-01, 9.61331000e-01, - 9.04209376e-01, 9.63892747e-01, 9.46209175e-01, 9.04518643e-01, - 7.26399734e-01, 9.83897979e-01, 8.27304272e-01, 3.32530991e-01, - 9.84515497e-01, 2.56890432e-01, 4.13745647e-02, 6.15384113e-02, - 1.01896215e-02, 9.91252119e-01, 7.41949546e-02, 5.08643664e-02, - 9.19594180e-01, 6.56879477e-01, 1.38321566e-01, 8.91272269e-01, - 3.76529356e-01, 1.43275785e-01, 8.49632410e-02, 4.14695708e-01, - 1.09868138e-01, 2.71223046e-01, 8.37391371e-01, 1.75748878e-01, - 7.46450754e-01, 2.62086328e-01, 3.02968832e-01, 3.08811921e-01, - 6.75112571e-01, 1.54663865e-01, 7.68687843e-02, 8.77842966e-01, - 5.95682123e-01, 8.84030026e-01, 4.11628111e-01, 1.39221484e-02, - 5.40001953e-01, 4.75558489e-01, 9.87355965e-01, 7.80989133e-01, - 9.13962355e-01, 2.22696195e-01, 5.78395818e-01, 8.08965138e-01, - 6.06214278e-01, 7.89805419e-01, 6.39241167e-01, 9.12456228e-01, - 1.67840880e-01, 3.53944938e-01, 4.39652426e-01, 9.72728897e-01, - 5.09008884e-01, 4.06519841e-01, 9.05467696e-01, 3.61380329e-01, - 8.36748412e-01, 8.27654293e-01, 3.69483653e-01, 2.35592710e-01, - 4.43410231e-01, 8.45589729e-02, 2.65186217e-01, 9.00911601e-01, - 8.37081370e-01, 9.94206284e-01, 6.27674149e-01, 2.83436085e-01, - 4.91578394e-01, 2.39388739e-01, 7.53775833e-01, 7.65900773e-01, - 7.15594596e-01, 6.91507628e-01, 8.68231103e-01, 8.27670658e-01, - 2.66069794e-02, 9.24833718e-01, 4.07264594e-01, 6.46532156e-01, - 3.05981566e-01, 6.72368241e-01, 9.48028447e-01, 7.57749971e-01, - 4.23917031e-01, 8.29638611e-01, 2.22636497e-02, 4.33986046e-01, - 2.89018838e-01, 7.81398654e-01, 3.39236836e-02, 2.46990497e-01, - 6.03205453e-01, 4.54589789e-01, 9.40588634e-01, 7.24938657e-01, - 3.25200097e-01, 1.35990964e-01, 6.30647885e-01, 2.49898974e-01, - 7.92871477e-01, 8.38301547e-01, 6.92965697e-01, 5.95539037e-03, - 6.93435428e-01, 1.17512906e-01, 1.07996451e-01, 6.80556483e-01, - 4.83315231e-01, 9.82720401e-01, 3.53397185e-01, 7.62348221e-01, - 8.62281735e-01, 7.43698891e-01, 5.63628921e-01, 4.61846055e-01, - 6.63495039e-01, 9.34262357e-01, 3.55006049e-02, 8.82918307e-02, - 9.63137670e-01, 5.25997210e-01, 7.84285486e-01, 1.57197155e-01, - 9.19628016e-01, 3.12345729e-01, 8.48558099e-01, 9.41241963e-01, - 8.04528060e-01, 1.86439955e-01, 8.55088666e-01, 6.05907190e-01, - 2.72833945e-01, 8.54406399e-02, 6.46909892e-01, 4.72546083e-02, - 6.74391082e-01, 3.70415944e-01, 8.16789315e-01, 8.12652539e-03, - 4.23180555e-01, 3.54543378e-01, 3.04230397e-01, 8.04708670e-01, - 6.91577567e-01, 2.96322435e-01, 4.61354184e-01, 5.93717371e-02, - 1.53499985e-01, 8.92148814e-01, 1.64638319e-01, 7.38604892e-01, - 6.02570691e-01, 5.34650510e-01, 6.68396934e-01, 8.02145367e-01, - 7.34817185e-01, 7.41494512e-01, 9.44356445e-01, 3.97851754e-01, - 8.03286601e-01, 7.80976959e-01, 6.49706333e-01, 5.25477011e-01, - 1.25350140e-01, 9.81939771e-01, 3.98778289e-01, 4.93460779e-01, - 8.29468443e-01, 3.66458821e-01, 2.18733806e-01, 3.66335915e-01, - 2.73011413e-01, 7.27958619e-01, 3.62424542e-01, 2.14509544e-01, - 4.13024987e-01, 4.72061154e-01, 5.53947740e-01, 5.31675692e-01, - 3.71925756e-01, 2.31208204e-01, 1.73726133e-01, 7.47059244e-01, - 6.83914622e-02, 1.77409894e-01, 5.17290543e-01, 1.70213457e-01, - 7.18947645e-01, 8.18895525e-01, 8.07188857e-01, 5.71988322e-02, - 3.47670155e-01, 4.16075155e-01, 9.26956424e-01, 2.32702268e-02, - 6.54650022e-01, 9.56034456e-01, 3.80220033e-02, 7.25930569e-01, - 9.85998591e-01, 8.77696544e-01, 6.53688575e-02, 3.71514876e-01, - 3.20639741e-01, 4.50013967e-01, 2.04994606e-01, 5.41234862e-01, - 8.28278185e-01, 8.40104449e-02, 7.62408153e-01, 9.74030597e-01, - 5.98201472e-01, 4.10348139e-01, 5.71331554e-01, 6.77575535e-01, - 5.00177981e-01, 7.83423781e-02, 3.78576641e-01, 9.11038480e-01, - 2.49289014e-01, 5.38592714e-02, 6.13534724e-01, 7.38466339e-01, - 7.27171126e-01, 4.74905476e-01, 9.40012900e-01, 4.44981968e-01, - 8.81997918e-01, 2.23525145e-01, 8.08694059e-01, 4.99111844e-01, - 6.79157051e-03, 2.19248046e-01, 9.13960278e-01, 5.24991491e-01, - 6.93940799e-01, 7.42648103e-01, 7.02214213e-01, 9.18667786e-01, - 7.59341472e-01, 3.54414552e-01, 9.46592781e-01, 5.20239076e-01, - 5.47405167e-01, 4.25788778e-01, 3.48108829e-01, 6.27264794e-01, - 8.95325979e-01, 9.33420332e-01, 3.82918759e-01, 5.54905966e-02, - 7.78169299e-01, 9.26901670e-01, 5.66105670e-01, 5.12692071e-01, - 5.34226058e-01, 8.66718175e-01, 7.84492694e-01, 1.68997042e-01, - 8.67033224e-02, 9.79202584e-01, 8.56753423e-01, 9.04184995e-01, - 5.00378023e-01, 7.46643152e-02, 3.29220649e-01, 4.98306376e-01, - 7.69615359e-01, 3.28224231e-01, 9.41188434e-01, 8.19528373e-01, - 5.93907766e-01, 5.98301237e-01, 3.85798398e-01, 6.75196282e-01, - 7.37105148e-01, 5.01794822e-01, 3.01794125e-01, 7.19154452e-01, - 6.40740024e-01, 6.12898801e-02, 5.37371628e-01, 3.27451153e-01, - 8.84910552e-01, 3.10629091e-01, 4.46631719e-01, 8.85742724e-01, - 6.83613510e-01, 2.07972972e-01, 4.93206267e-01, 3.74151928e-01, - 9.12954066e-01, 5.49843441e-01, 6.10165821e-01, 1.72061990e-01, - 8.99540060e-01, 5.06387833e-01, 2.52932211e-01, 3.80791581e-01, - 7.45111439e-01, 3.34417679e-01, 8.53005515e-01, 1.53964676e-02, - 7.80223373e-01, 8.03453467e-01, 5.40362876e-01, 5.60155057e-01, - 5.32810533e-01, 7.43661218e-01, 4.12663312e-01, 1.92132141e-01, - 6.16617146e-01, 4.86322891e-01, 9.37376605e-01, 5.52481104e-01, - 9.63440251e-01, 1.99438737e-01, 8.83420843e-01, 4.05579554e-02, - 1.34087876e-01, 5.26339200e-01, 7.48386928e-01, 5.94725741e-01, - 6.50249741e-01, 3.62297757e-01, 1.55316865e-01, 2.74679259e-01, - 2.51148216e-01, 5.05888061e-01, 7.50971491e-02, 8.60876909e-01, - 7.25551105e-01, 4.93888271e-01, 6.89908477e-01, 3.16459329e-01, - 7.02989702e-01, 9.46942980e-01, 7.07153678e-01, 9.41226034e-01, - 1.42636649e-01, 7.36429712e-01, 6.03964454e-01, 9.89378761e-01, - 6.18206628e-01, 9.91291847e-01, 8.66409471e-01, 2.45899762e-01, - 5.20574298e-01, 6.91097441e-01, 7.58355116e-01, 9.10371369e-01, - 6.85451953e-01, 5.39838611e-01, 4.94642157e-01, 2.72929998e-01, - 1.70949276e-01, 1.33503240e-01, 9.60196229e-01, 2.65671261e-01, - 9.49609345e-01, 3.60688343e-01, 5.24134421e-02, 7.11077155e-01, - 9.33813206e-01, 5.15476454e-01, 2.77628556e-01, 8.13224016e-01, - 1.42105292e-03, 7.86922642e-01, 1.56669917e-01, 4.65061482e-01, - 7.43575610e-01, 7.92485799e-01, 3.48647119e-01, 3.16826059e-01, - 5.89802524e-01, 7.39660055e-01, 3.13570895e-01, 8.99993136e-01, - 2.96715237e-01, 3.83340615e-01, 6.08502076e-01, 7.68345205e-01, - 1.60487380e-02, 7.79764476e-01, 1.00886185e-01, 5.94645519e-01, - 4.21534301e-01, 5.63961951e-01, 9.09718817e-01, 4.39485110e-01, - 1.93389833e-01, 6.80064195e-01, 4.43028888e-01, 5.56237485e-01, - 5.86496876e-01, 2.31257921e-01, 9.61202925e-01, 4.59793037e-01, - 5.61479458e-01, 8.77234565e-01, 6.05507053e-01, 2.03064972e-01, - 9.23516956e-01, 8.32189173e-01, 7.14766263e-01, 6.00909692e-01, - 4.75369769e-01, 2.52192755e-01, 1.01192654e-01, 1.82640578e-01, - 6.12079821e-01, 2.91314009e-01, 3.38339866e-01, 3.25244880e-01, - 4.28193726e-01, 8.38819570e-01, 2.66068046e-01, 5.77997609e-01, - 6.33842230e-01, 8.59226768e-01, 5.47721282e-01, 4.51013011e-01, - 1.41933382e-01, 1.58233176e-01, 7.36274517e-01, 8.77079133e-01, - 3.64500767e-01, 1.06048980e-01, 8.70183348e-01, 2.47642294e-01, - 1.63214503e-01, 7.76344248e-01, 2.63572879e-01, 9.04422771e-01, - 3.31230428e-01, 1.89025913e-01, 5.78611543e-01, 4.90528171e-01, - 7.64302624e-01, 3.01995592e-01, 6.13056209e-01, 8.13825825e-01, - 2.57329336e-01, 1.66718878e-01, 7.94592534e-01, 8.86334436e-01, - 6.10374964e-01, 2.87771705e-01, 5.45612401e-01, 4.37346903e-01, - 5.71538248e-01, 3.33973142e-02, 5.94744871e-01, 1.97806492e-01, - 1.22829759e-01, 2.47705589e-01, 1.29666014e-01, 1.72537025e-01, - 6.30226634e-01, 2.97305793e-01, 2.41658241e-01, 8.03958728e-01, - 6.56715667e-01, 2.16922109e-01, 3.87718346e-01, 7.24736100e-01, - 1.33184518e-01, 9.04524258e-01, 6.62300515e-02, 5.62362662e-01, - 8.70343960e-01, 1.43343922e-01, 7.57798720e-03, 6.87858407e-01, - 2.46865078e-01, 4.12706952e-01, 8.45243376e-01, 1.74276134e-01, - 4.21790519e-01, 7.07196936e-02, 2.67299318e-01, 2.66312175e-01, - 5.44482024e-01, 3.61060931e-01, 6.62722697e-01, 1.73284158e-01, - 8.92379290e-01, 8.42237465e-01, 5.88225553e-01, 3.19755374e-01, - 3.73048056e-01, 9.91540349e-01, 8.81802425e-01, 8.90415763e-01, - 3.21600364e-01, 5.75105765e-01, 2.64081085e-01, 6.35349535e-01, - 9.96842609e-01, 6.06757137e-01, 5.43231059e-01, 6.31772309e-01, - 1.28604009e-01, 3.85296434e-01, 9.66562077e-01, 9.24993565e-01, - 4.08646101e-01, 2.57195032e-01, 4.99559018e-01, 3.30590905e-01, - 2.75753925e-01, 4.24663958e-01, 1.99726024e-01, 6.09615831e-01, - 6.93912387e-02, 5.85029154e-01, 6.29352772e-01, 6.48178386e-01, - 3.77259531e-01, 5.04125465e-01, 5.56632153e-01, 2.48201529e-01, - 5.17730329e-01, 1.15699874e-01, 3.77347640e-02, 6.32627490e-01, - 9.86774371e-01, 7.70017805e-01, 7.88518452e-01, 4.74742065e-01, - 5.87766822e-01, 8.70387311e-01, 5.84113887e-01, 8.97441417e-01, - 1.78428301e-02, 3.98066215e-01, 1.34594086e-01, 7.18253859e-01, - 5.27009831e-01, 4.03080649e-01, 7.23440561e-01, 4.27520855e-01, - 3.68026660e-01, 7.11538788e-01, 6.67478414e-01, 2.32871924e-02, - 7.84880832e-01, 1.45336142e-01, 5.75668290e-01, 8.13004304e-01, - 2.05814529e-01, 9.47914810e-01, 6.44562983e-01, 8.48629796e-01, - 3.40464869e-01, 9.64319301e-01, 2.40078628e-01, 4.97184491e-01, - 7.40368203e-01, 5.74889758e-01, 1.72997562e-01, 7.76217188e-01, - 9.53144710e-02, 1.26942232e-02, 1.20893644e-01, 1.79072967e-01, - 6.96910859e-01, 6.21238277e-01, 9.62174814e-01, 9.86630646e-01, - 4.38483396e-01, 3.71595886e-01, 2.12381320e-01, 2.32395134e-01, - 1.98585395e-01, 9.44997425e-01, 2.99058186e-01, 2.82235207e-01, - 9.85614304e-01, 4.23673172e-01, 8.52717040e-01, 3.74433598e-01, - 9.16439272e-01, 6.08616508e-02, 2.79568454e-01, 6.89427200e-01, - 4.17028474e-01, 5.93868290e-01, 8.45153021e-01, 5.78780507e-01, - 8.99834348e-01, 3.94819540e-01, 1.58206722e-01, 6.09096431e-02, - 4.12309146e-01, 7.70781904e-01, 8.14126044e-01, 1.53080816e-02, - 1.29457919e-02, 8.34272811e-01, 5.84588027e-01, 5.01099790e-01, - 9.30890899e-01, 5.35819804e-01, 5.97723141e-01, 7.18482652e-02, - 7.64118304e-01, 6.00457393e-01, 1.51300499e-03, 7.32316014e-01, - 8.49944821e-01, 1.81182730e-01, 3.58653875e-01, 5.84862288e-01, - 7.49653254e-01, 6.25522929e-01, 9.80562135e-01, 1.03533965e-01, - 9.38744698e-01, 9.55887217e-01, 9.90515311e-01, 8.21634713e-01, - 6.77408570e-01, 2.99337349e-01, 2.45240019e-01, 8.14416151e-01, - 5.12592734e-01, 6.62767568e-01, 3.33403905e-01, 6.61761691e-01, - 7.49025551e-01, 5.87393442e-01, 2.07238651e-01, 4.68745758e-01, - 8.62035612e-01, 2.41516814e-01, 9.28035284e-01, 7.82432920e-01, - 7.32491002e-01, 3.20663204e-01, 5.59083780e-01, 7.05581001e-01, - 9.46183726e-01, 1.06006830e-01, 7.94781718e-01, 3.17211578e-01, - 4.12467767e-01, 1.55854106e-01, 1.40098765e-01, 6.89685903e-01, - 1.20028956e-01, 8.12410120e-01, 3.57096450e-01, 3.83630501e-01, - 3.81407329e-01, 5.44225083e-01, 1.74986076e-01, 4.77592620e-01, - 1.21944496e-01, 8.34478648e-01, 6.96490835e-01, 5.49827508e-01, - 5.47515640e-02, 1.70561469e-01, 2.77912184e-01, 4.04441910e-01, - 9.97193103e-01, 2.78272674e-01, 2.40056510e-02, 2.51853142e-01, - 3.34877656e-01, 2.31801168e-01, 2.46598202e-01, 8.52646141e-01, - 1.93409117e-01, 7.00411651e-01, 6.32489788e-01, 6.47269641e-02, - 2.51353228e-01, 8.17180352e-01, 4.62356863e-01, 5.27273877e-01, - 7.05969283e-01, 7.51765874e-01, 8.35492845e-01, 1.35506394e-01, - 2.61530320e-01, 3.20682888e-01, 3.18954597e-01, 3.07139485e-01, - 2.61962914e-01, 3.30613880e-01, 9.07200826e-02, 6.06202858e-01, - 8.36747305e-01, 3.55109173e-01, 4.94941940e-01, 1.25820220e-01, - 5.17048715e-02, 7.63000235e-02, 2.67274492e-01, 9.92138192e-01, - 2.78034163e-01, 6.65323883e-01, 7.54894601e-01, 2.19449131e-01, - 3.68750021e-01, 8.64247646e-01, 9.63748957e-01, 9.64750608e-01, - 2.24297632e-01, 3.39698952e-01, 9.94229340e-01, 6.97743370e-01, - 5.83625125e-01, 4.93055202e-01, 6.49122312e-01, 7.06328355e-01, - 1.26333641e-01, 3.80115175e-01, 2.28449133e-01, 2.22767825e-01, - 8.48205971e-01, 4.65934951e-01, 3.72549692e-01, 8.28956277e-01, - 3.36007180e-01, 2.35133544e-01, 5.59771139e-02, 9.54936584e-01, - 8.42164353e-01, 1.80391518e-01, 7.38924665e-01, 6.87395679e-01, - 1.99388436e-01, 5.99826951e-01, 9.66142085e-01, 7.51649586e-01, - 9.36096446e-01, 4.45870514e-01, 7.39956306e-01, 5.39705491e-01, - 3.69104773e-01, 6.82662294e-01, 8.56457822e-01, 4.07561951e-01, - 2.58861803e-01, 9.29644383e-01, 8.69500431e-01, 7.26341279e-01, - 6.00250300e-01, 2.57792159e-01, 6.47317808e-01, 9.74470843e-01, - 2.93003448e-01, 7.56220287e-01, 4.17122105e-01, 1.41783139e-01, - 6.45526915e-01, 7.94223310e-01, 2.30590052e-01, 5.73338874e-01, - 9.57619287e-01, 9.07885388e-01, 2.12735892e-01, 7.08940158e-01, - 1.50321098e-02, 8.20776954e-01, 1.40719237e-01, 3.22583922e-02, - 4.65625243e-01, 6.90417738e-01, 9.84318792e-01, 1.16394384e-01, - 6.35669181e-01, 9.37719355e-01, 2.74008417e-01, 4.57251005e-01, - 2.49569868e-01, 1.69433953e-02, 3.17662825e-02, 1.59587102e-01, - 7.83358255e-01, 6.77477003e-01, 7.83744446e-01, 7.62895899e-01, - 5.68819962e-01, 7.29331745e-01, 4.19426118e-01, 7.77328268e-01, - 5.88216444e-01, 9.97114683e-01, 4.77458782e-01, 1.07676258e-01, - 9.78465480e-01, 6.28285209e-02, 2.38397980e-01, 6.57846188e-01, - 5.48751029e-01, 1.24678227e-01, 7.58402711e-02, 9.71420260e-01, - 5.47550424e-01, 4.19757868e-01, 7.22052889e-01, 8.02164564e-01, - 4.43636390e-01, 1.58928137e-01, 4.24335396e-01, 2.12197261e-01, - 1.08836651e-01, 8.29052377e-01, 3.77888868e-01, 7.81084194e-01, - 7.78429714e-01, 3.90945690e-01, 6.51912226e-01, 2.88348822e-01, - 7.23901852e-01, 6.52715823e-01, 5.43731436e-02, 8.78512280e-01, - 6.60066267e-01, 8.20515209e-01, 4.42901526e-02, 5.13618862e-01, - 3.95231190e-01, 3.71209918e-01, 5.00722473e-01, 1.88894885e-01, - 9.06948616e-01, 8.52132921e-01, 1.29778705e-01, 1.43383305e-01, - 8.46342969e-01, 1.48545625e-01, 5.42216158e-01, 2.13416397e-01, - 6.73574223e-01, 5.22300826e-01, 5.86481435e-01, 4.58074668e-01, - 7.44556950e-02, 7.69430099e-02, 8.30101103e-01, 9.65982624e-01, - 6.09200262e-01, 6.71005983e-01, 9.92674306e-01, 9.92650495e-01, - 2.00438023e-01, 9.61423464e-01, 3.34473832e-01, 9.48197375e-01, - 4.39200472e-01, 7.76863250e-01, 5.69253833e-01, 5.70025518e-01, - 3.68976739e-01, 8.18171426e-01, 7.58481591e-02, 3.19808784e-01, - 4.57668288e-01, 1.44869379e-01, 6.78464367e-01, 1.66065777e-01, - 7.74631979e-01, 3.52758183e-01, 4.91845612e-01, 7.15016324e-01, - 4.94926235e-01, 8.50143184e-01, 7.68002689e-01, 2.80428378e-01, - 7.64445140e-01, 9.60741126e-01, 8.40453688e-01, 2.25481953e-01, - 5.84217713e-01, 6.63733112e-01, 8.20469002e-02, 5.03460927e-01, - 6.15793143e-01, 9.63304092e-01, 9.65981107e-01, 2.97332270e-01, - 4.54251208e-01, 9.26621241e-01, 1.08304032e-01, 5.43997217e-01, - 8.00307964e-01, 5.38281642e-01, 9.64531727e-01, 5.80528855e-01, - 6.92791319e-01, 4.21506325e-01, 3.42012123e-01, 4.12459301e-01, - 6.44631161e-01, 1.85067683e-02, 7.33214675e-01, 1.42917039e-01, - 5.51204686e-01, 2.97128845e-01, 6.87057014e-01, 3.28233924e-01, - 8.97879000e-01, 9.78933901e-01, 1.04951389e-01, 2.50031726e-01, - 9.95941262e-01, 5.83330828e-01, 5.72222748e-01, 2.88462307e-01, - 3.42147380e-01, 7.82169432e-01, 3.70059110e-01, 4.52782248e-01, - 8.07919395e-01, 3.95487902e-01, 7.02669357e-02, 8.71997657e-01, - 2.05374408e-01, 2.39741123e-01, 7.95127425e-01, 3.47019036e-01, - 5.06856826e-01, 3.20973776e-01, 2.05599215e-01, 4.03323806e-01, - 2.02475510e-01, 1.76500710e-01, 7.45973346e-01, 8.02962844e-01, - 2.86354442e-01, 5.95489096e-01, 7.43402988e-01, 2.62402528e-01, - 9.79921875e-01, 2.46865962e-01, 2.84770027e-01, 2.27352503e-02, - 7.96055075e-02, 2.12807086e-01, 9.82460388e-01, 5.59973629e-01, - 8.88765969e-01, 5.58124493e-01, 5.67634068e-01, 7.21318629e-01, - 5.28885789e-01, 4.43899006e-01, 3.89530240e-01, 5.31093600e-01, - 5.86830474e-01, 8.51280942e-01, 9.21934422e-01, 4.24711396e-01, - 5.55468787e-01, 2.36251878e-01, 6.57752151e-01, 8.01006332e-01, - 1.40256336e-01, 1.66563629e-01, 4.01277343e-01, 4.50459390e-01, - 7.94146451e-01, 4.34760883e-01, 8.24390211e-01, 7.02275970e-01, - 3.95060222e-01, 5.73282605e-02, 8.71138034e-03, 7.28635465e-01, - 8.45552224e-01, 4.70925234e-01, 6.78796265e-02, 2.07263097e-01, - 5.86946139e-01, 9.06559029e-01, 6.51919310e-01, 7.60877329e-01, - 6.76870797e-01, 4.00789965e-01, 3.93900812e-01, 3.51690776e-01, - 5.23143230e-04, 3.78857317e-01, 5.43222132e-01, 8.16578228e-01, - 9.30324851e-01, 6.46214332e-01, 2.61310347e-01, 2.70396034e-02, - 7.32481401e-01, 5.81694842e-01, 7.58738779e-03, 7.90227361e-01, - 3.00126457e-01, 4.14882874e-02, 7.08497948e-01, 5.60693385e-01, - 5.47778566e-02, 3.39501905e-01, 9.68503497e-01, 2.82392648e-01, - 6.19676991e-01, 5.58693445e-01, 2.42016331e-01, 6.59966678e-01, - 9.39823398e-02, 8.91229971e-01, 3.64346405e-01, 2.95260491e-01, - 1.36980210e-01, 3.30952220e-01, 7.43274694e-01, 4.48712998e-01, - 5.79190352e-01, 5.05283697e-02, 2.46807884e-01, 6.58511828e-01, - 7.35609681e-01, 9.33688813e-01, 7.40011895e-03, 9.56898332e-01, - 2.60040059e-01, 8.32883745e-01, 3.99693073e-01, 2.42512322e-01, - 5.20237365e-01, 3.44008476e-01, 9.06945518e-01, 6.30303009e-01, - 4.15536907e-01, 7.75681961e-01, 8.68198307e-01, 1.89745356e-01, - 9.58812180e-01, 3.39231168e-01, 7.13284513e-01, 5.44619342e-01, - 6.90752904e-01, 3.41919481e-01, 9.17002377e-01, 4.42660426e-01, - 2.97611223e-01, 2.09665584e-01, 7.15700835e-01, 4.08069844e-01, - 9.37477590e-01, 7.31847963e-01, 2.24883023e-01, 6.42080345e-01, - 5.62037302e-01, 3.66030416e-02, 1.26555140e-01, 2.66109804e-01, - 4.11514421e-01, 6.89398564e-01, 3.24382926e-01, 7.09235595e-01, - 8.36059819e-01, 1.54755053e-01, 2.55443940e-01, 1.38511230e-01, - 1.28580165e-01, 4.65390959e-01, 5.74969736e-01, 1.87437843e-01, - 3.08632637e-01, 9.98398382e-01, 8.31796483e-01, 7.07153453e-01, - 4.50038297e-02, 7.44671234e-03, 1.86645396e-01, 8.99905024e-01, - 4.75494879e-01, 2.75352305e-01, 6.19095221e-01, 9.88322601e-01, - 7.43618748e-01, 5.98011517e-01, 6.11113136e-01, 9.59259852e-01, - 6.46648391e-01, 1.94647377e-02, 6.13853105e-02, 1.36690848e-01, - 6.59128521e-01, 8.29382985e-02, 7.26147650e-01, 9.12885719e-01, - 7.11153104e-01, 4.37900399e-01, 2.14801191e-01, 5.73226766e-01, - 4.47518472e-02, 6.49675931e-01, 2.03952495e-01, 9.71144660e-01, - 7.02592556e-01, 4.16915759e-01, 8.10849851e-01, 1.31426871e-01, - 5.34316452e-01, 3.73126310e-02, 7.81773874e-01, 4.16333390e-01, - 9.81162386e-01, 3.85792561e-01, 6.09930953e-02, 5.31823785e-02, - 5.22322062e-01, 7.74411477e-01, 4.86276490e-01, 5.50963925e-01, - 2.33599095e-01, 3.98549372e-01, 4.82391321e-01, 5.70988844e-01, - 1.78844466e-01, 9.49290226e-01, 4.74758248e-01, 2.51411034e-01, - 6.26682370e-01, 5.27678789e-02, 5.18200357e-01, 9.91857191e-01, - 2.55883271e-01, 9.12084937e-01, 4.98020624e-01, 2.46761272e-01, - 3.74236562e-01, 3.25448819e-01, 6.15502212e-01, 5.56337605e-02, - 2.77707979e-01, 9.12936667e-01, 7.69895125e-01, 9.55639929e-01, - 8.27437886e-02, 5.72907267e-01, 1.29786295e-02, 6.35965414e-01, - 5.76948360e-01, 6.78419034e-01, 8.85029727e-01, 7.54937124e-01, - 1.61134035e-02, 8.62421529e-01, 7.60092328e-01, 2.04175394e-01, - 7.06165401e-01, 2.22521842e-01, 2.99530561e-01, 9.83097374e-01, - 7.52501116e-01, 4.77643358e-01, 8.48989955e-01, 7.07797363e-01, - 4.57460071e-01, 8.76173059e-01, 7.70355145e-01, 9.19190360e-01, - 1.76969224e-01, 6.00997624e-01, 5.45117516e-01, 3.78660623e-01, - 8.95231199e-01, 5.13465555e-01, 7.14449756e-01, 7.67966306e-01, - 8.89714449e-01, 7.14009679e-02, 5.52928812e-01, 7.86021850e-01, - 9.41163034e-01, 4.67822478e-01, 8.05915121e-02, 5.30276186e-01, - 7.65467203e-01, 3.73808835e-01, 4.91156378e-01, 3.58664602e-01, - 2.26904088e-01, 3.16859132e-01, 3.73453110e-01, 6.30708292e-01, - 5.12523662e-01, 8.81846398e-01, 6.92017219e-01, 9.48869807e-01, - 7.92591089e-01, 9.24534687e-01, 3.28455072e-01, 7.45136433e-01, - 3.40401009e-01, 3.40231921e-01, 4.77734018e-01, 6.50807174e-01, - 7.98767642e-01, 7.06227188e-01, 6.25502118e-01, 8.91886969e-01, - 6.06700448e-01, 3.41539951e-01, 9.32214524e-01, 4.34983330e-01, - 3.45254713e-01, 3.57136166e-01, 9.85057476e-01, 6.65219177e-01, - 6.79501220e-01, 4.20034542e-01, 3.56116781e-02, 3.61296822e-01, - 1.28159608e-01, 9.39005671e-01, 4.92631448e-01, 2.24843838e-01, - 2.62851024e-01, 4.79554042e-02, 2.97862523e-01, 8.19822181e-01, - 1.47177192e-01, 5.31670502e-01, 2.76609400e-02, 7.58205905e-01, - 8.45054829e-01, 3.94621114e-01, 1.40304529e-01, 2.81893546e-01, - 4.03035670e-01, 9.42132100e-01, 2.97318846e-01, 2.27801447e-01, - 4.05697432e-01, 4.87274269e-01, 3.00716313e-01, 4.82574170e-02, - 4.44931201e-01, 8.38566584e-01, 2.54748403e-01, 7.95011807e-01, - 5.39238275e-01, 5.30986168e-01, 4.98400033e-01, 9.89188053e-01, - 3.61317622e-01, 1.90124545e-01, 2.55053949e-01, 5.99007609e-01, - 3.17359682e-01, 9.47342893e-01, 1.39071107e-01, 7.91886755e-01, - 1.44858792e-01, 9.99004213e-01, 5.58560202e-02, 8.46648208e-02, - 6.87166284e-01, 8.35783607e-01, 4.81347011e-01, 5.84029341e-01, - 2.02951199e-01, 3.95813602e-01, 9.49057551e-02, 4.47859372e-02, - 2.68994839e-01, 7.07165004e-01, 8.87825246e-01, 6.12770437e-01, - 2.34321343e-01, 5.85709437e-01, 8.72671869e-02, 1.39896827e-01, - 5.09333843e-01, 7.27710068e-01, 7.38663637e-01, 5.50438938e-01, - 9.31590149e-01, 4.04769063e-01, 2.73018682e-02, 5.07490305e-01, - 8.74367997e-01, 6.77101075e-01, 2.33192320e-01, 5.09244160e-01, - 6.82129724e-01, 9.93948690e-01, 4.36099996e-01, 4.68337581e-02, - 6.22690760e-01, 4.44871189e-01, 3.90277745e-01, 7.70136882e-01, - 8.08790015e-01, 3.85178146e-02, 1.74645856e-01, 4.44510159e-02, - 5.47737664e-01, 8.02671146e-01, 2.78333350e-01, 6.37671858e-01, - 7.00968580e-01, 9.43903614e-01, 7.66194212e-01, 1.32352701e-01, - 6.36437044e-01, 2.79465972e-01, 6.76586377e-02, 1.07716871e-01, - 4.42186585e-01, 7.08154504e-01, 9.38951281e-01, 4.01040842e-01, - 7.77139248e-01, 5.16737445e-01, 4.71288711e-01, 5.68391592e-01, - 4.53398096e-01, 5.25239515e-01, 1.23416489e-01, 7.00305807e-01, - 3.55456337e-01, 6.02767565e-01, 4.65117973e-01, 3.66442098e-01, - 3.59252014e-01, 9.77318209e-02, 2.54376451e-01, 9.92153383e-01, - 8.44311596e-01, 3.33511657e-01, 3.21187113e-01, 9.44155515e-01, - 9.58279383e-01, 6.19696671e-01, 6.83133956e-01, 9.53238889e-01, - 9.52786182e-01, 7.70795489e-01, 1.19985029e-01, 8.80668885e-01, - 7.92041990e-01, 5.34508783e-01, 8.61126458e-01, 7.30015303e-01, - 2.44730644e-01, 3.85520206e-01, 5.14773006e-01, 9.30435191e-01, - 2.90506950e-01, 1.59853133e-01, 5.33678023e-01, 4.06483043e-01, - 9.83312639e-01, 7.92208535e-01, 4.48549604e-01, 9.29596783e-01, - 8.29209388e-01, 4.13746197e-01, 2.78522894e-01, 1.24698598e-01, - 9.95279157e-01, 4.97658654e-01, 3.47725026e-01, 8.12280996e-01, - 2.05401829e-01, 6.11935271e-01, 6.64070705e-01, 6.97104230e-01, - 5.20320333e-01, 8.07002465e-02, 2.65561088e-01, 5.04476612e-01, - 2.53677297e-01, 2.22037103e-02, 5.56679999e-01, 2.13880244e-02, - 5.26273785e-02, 9.16837638e-01, 8.06240972e-01, 7.28558889e-01, - 3.98628439e-01, 4.64297787e-01, 1.53553483e-01, 1.64207909e-01, - 6.04853572e-01, 5.36962911e-01, 5.18696963e-01, 3.55893557e-01, - 1.74758575e-02, 3.08559150e-01, 9.52638311e-01, 8.47241893e-01, - 5.00552846e-01, 2.56364563e-01, 1.23799145e-01, 1.47851097e-01, - 3.45581385e-01, 9.03615026e-01, 2.23265175e-01, 4.96256433e-01, - 7.67961045e-01, 7.09507947e-01, 6.01350814e-01, 1.31313992e-01, - 6.91281767e-01, 3.45817624e-01, 2.84693078e-02, 3.07414436e-01, - 3.33561761e-01, 8.14277773e-01, 4.36154703e-01, 7.78464078e-01, - 6.40600546e-02, 8.98374698e-01, 1.48836952e-01, 6.87839652e-01, - 2.58203274e-01, 2.53358829e-02, 2.64164118e-01, 2.24107570e-01, - 9.60626248e-01, 6.44587610e-01, 2.26682168e-01, 1.24678631e-01, - 1.37189111e-01, 5.47457097e-01, 2.45986556e-01, 6.27171911e-01, - 4.62105354e-01, 5.45884629e-01, 3.98675650e-01, 9.20427902e-02, - 5.79638610e-01, 6.03795142e-01, 5.95348766e-01, 1.24123121e-01, - 3.59812080e-01, 8.97200870e-01, 1.36096808e-01, 9.21413055e-01, - 2.30924025e-01, 2.32271947e-01, 8.47191024e-01, 4.44227105e-01, - 5.02807640e-01, 8.87944464e-01, 6.73280097e-01, 9.00854692e-01, - 4.45951722e-01, 8.44607166e-01, 9.30937171e-01, 2.78999887e-01, - 5.85286759e-01, 7.78448585e-01, 7.42990033e-01, 4.60412735e-01, - 3.68970066e-01, 8.44483407e-01, 9.76292697e-01, 5.57247712e-01, - 2.90144827e-02, 6.40377843e-02, 5.04281811e-01, 3.08020642e-01, - 6.73448304e-01, 6.41708285e-01, 3.20919116e-01, 8.60140279e-02, - 8.76827989e-01, 3.21997580e-01, 2.47139868e-01, 2.81166389e-01, - 6.49057366e-01, 4.43597391e-01, 6.80117301e-02, 6.92262024e-01, - 2.89536739e-01, 5.18961403e-01, 7.51654551e-01, 1.07850946e-01, - 9.13298767e-01, 6.20937411e-01, 9.51990513e-01, 4.60408615e-02, - 5.95896084e-01, 2.40755336e-01, 7.04904710e-01, 8.89364841e-01, - 8.12797679e-01, 4.59725452e-01, 5.42419112e-01, 5.83490243e-01, - 6.57364847e-01, 7.10158049e-01, 9.31392924e-01, 3.42382488e-01, - 2.43136684e-01, 7.94487603e-01, 1.33636000e-01, 5.98565779e-01, - 4.79356515e-01, 2.78107779e-01, 1.02616971e-01, 7.97586145e-01, - 5.25068076e-01, 5.81882776e-01, 6.18754490e-02, 4.66314066e-01, - 1.95333916e-01, 3.44818394e-01, 3.24977977e-01, 2.56977928e-01, - 3.38226285e-01, 9.39668269e-02, 3.96353133e-01, 7.88433242e-01, - 8.47038548e-01, 6.88273075e-01, 3.15373368e-01, 1.66250014e-01, - 8.14076813e-01, 4.19474154e-01, 2.31482016e-01, 3.98914298e-01, - 7.90044337e-01, 1.78959492e-01, 6.56782330e-01, 4.51813294e-01, - 6.23312999e-01, 8.31178219e-01, 6.53066574e-01, 9.12065522e-01, - 5.56236102e-02, 4.36703335e-01, 2.53798590e-01, 9.43292997e-01, - 5.03324145e-02, 1.76916441e-01, 2.26853091e-01, 3.55773145e-01, - 3.20730959e-01, 7.51416299e-01, 9.52854353e-01, 3.23625963e-01, - 7.30134884e-01, 7.56065705e-02, 1.59748525e-01, 1.93278694e-01, - 8.00096778e-01, 1.10635984e-01, 4.55346304e-01, 6.71278245e-01, - 6.67190531e-01, 6.39218459e-01, 4.28078739e-01, 9.02470778e-01, - 4.48024608e-01, 5.33436692e-01, 6.77335653e-02, 6.31257708e-01, - 3.17529787e-01, 6.15566019e-01, 5.88019537e-01, 1.28779729e-01, - 3.24475462e-02, 1.29975240e-01, 3.96632091e-01, 6.68507605e-01, - 5.98634700e-01, 6.98114204e-01, 2.85172283e-01, 5.92092760e-01, - 9.43681575e-02, 3.11732964e-01, 6.69661926e-01, 6.19033207e-02, - 3.15569199e-01, 8.24018427e-01, 2.72827084e-01, 2.12553118e-02, - 5.44778065e-01, 4.26126668e-01, 3.43077971e-01, 9.38969273e-01, - 6.79067818e-01, 8.20544923e-01, 3.91665685e-01, 8.40458227e-02, - 4.68754453e-01, 7.94008161e-01, 6.28415682e-01, 4.10742878e-01, - 6.38712164e-01, 2.48962420e-02, 5.91028828e-01, 9.58334342e-01, - 8.69295404e-01, 2.53102989e-01, 5.17612544e-01, 8.16636860e-01, - 4.54036299e-01, 9.87268903e-01, 6.42350149e-01, 8.94638842e-01, - 2.81913893e-01, 7.38329591e-01, 4.97222656e-01, 1.50687871e-01, - 6.58082501e-01, 9.01998958e-01, 8.78885705e-01, 5.72693786e-02, - 5.66994609e-01, 1.86903723e-01, 3.03128279e-02, 6.55577712e-01, - 1.48136670e-01, 3.66744929e-02, 4.00643997e-01, 2.16833884e-01, - 4.28637098e-01, 5.93251499e-01, 3.10099576e-01, 3.56347907e-01, - 4.80633919e-01, 6.95479794e-01, 3.82901881e-01, 4.86445719e-01, - 6.90776257e-01, 5.27943762e-01, 1.54057492e-01, 3.81399626e-01, - 5.27223710e-01, 2.75750893e-01, 9.06080430e-01, 3.68589759e-01, - 5.58721041e-01, 3.88216990e-01, 4.20036648e-01, 3.90405436e-01, - 8.35696253e-02, 6.47239540e-01, 9.02878426e-01, 2.20779035e-01, - 2.09764394e-01, 9.01694507e-01, 4.17614713e-01, 2.11505870e-01, - 3.04049682e-01, 6.50487405e-01, 5.79122544e-01, 8.85505215e-02, - 5.41049364e-01, 9.58523804e-01, 7.65869000e-02, 8.18691445e-01, - 7.56380310e-01, 6.91066947e-02, 5.58165939e-01, 3.33783422e-01, - 8.10890357e-01, 8.02739567e-02, 4.60010558e-01, 6.02989674e-01, - 8.18790942e-01, 9.51333826e-01, 7.58956860e-01, 2.97026768e-01, - 4.89478781e-01, 7.32401666e-01, 5.59447345e-01, 8.89480242e-01, - 4.60698134e-01, 5.59130888e-01, 6.73016830e-01, 3.98687801e-01, - 1.62702070e-01, 9.90090958e-01, 3.70339710e-01, 9.69956667e-01, - 2.84279349e-01, 5.33610153e-01, 4.23134696e-01, 1.70047738e-01, - 1.30152889e-03, 9.88960317e-01, 4.70958919e-01, 6.11701914e-01, - 3.34924421e-01, 6.18826931e-01, 6.75401088e-01, 9.78653009e-01, - 8.24862312e-01, 7.35813539e-02, 5.92246958e-01, 1.73297526e-01, - 2.71078644e-01, 4.31840115e-01, 6.42635735e-01, 6.65594543e-01, - 6.87719832e-01, 2.85053867e-01, 6.72791677e-01, 8.13775595e-01, - 6.41472912e-01, 1.64871174e-01, 4.04255199e-01, 1.34913794e-01, - 5.80228604e-01, 7.12544926e-01, 6.67000888e-04, 8.60751469e-01, - 7.73103686e-01, 5.09803470e-01, 1.38742504e-01, 4.44729321e-01, - 6.04426510e-01, 8.51775434e-01, 9.20191017e-01, 2.23018119e-01, - 1.13988927e-01, 3.27425393e-02, 7.72343135e-01, 2.59325047e-02, - 7.58667597e-01, 3.94506976e-01, 1.51791171e-01, 8.66853950e-01, - 9.78480502e-01, 3.24678356e-01, 8.43552026e-01, 2.93808597e-01, - 9.75134987e-01, 8.47768039e-01, 7.74106338e-01, 5.90672167e-01, - 8.34666097e-01, 1.68905661e-01, 7.64858239e-01, 1.80665783e-02, - 8.03131088e-01, 8.89208355e-01, 6.37933426e-01, 1.59727271e-01, - 7.51656604e-02, 2.08827448e-01, 8.84935456e-01, 6.72354715e-01, - 1.52415078e-01, 6.65886720e-01, 5.82533752e-01, 4.16740892e-01, - 1.27180431e-01, 9.81197907e-01, 2.02190637e-01, 4.28024097e-01, - 4.98733443e-01, 4.87579983e-01, 4.84558001e-01, 2.92440812e-01, - 2.52710137e-01, 7.79116604e-01, 1.75135175e-01, 9.11629390e-01, - 3.67603592e-01, 4.00705048e-02, 2.78911824e-01, 9.04293122e-01, - 5.73009839e-02, 4.67027747e-01, 7.46474494e-01, 2.89453700e-01, - 7.85534327e-01, 3.22750344e-01, 2.66166390e-01, 1.26029132e-01, - 4.42315884e-01, 9.34142069e-01, 8.81743162e-01, 6.09369659e-01, - 9.44759200e-01, 9.00191783e-02, 1.64306150e-01, 5.99951432e-01, - 2.86214068e-01, 2.69497132e-01, 1.45099944e-01, 7.41321191e-01, - 5.93012397e-01, 1.50296977e-01, 1.40914168e-01, 5.42359671e-01, - 9.45060202e-01, 4.11114012e-01, 7.06014805e-01, 2.93229759e-02, - 2.63689713e-01, 5.50893307e-01, 5.71239434e-01, 6.36056158e-01, - 5.04706937e-01, 2.49390958e-01, 7.11128783e-01, 6.12824706e-01, - 6.65674403e-01, 9.75215008e-01, 5.74364962e-01, 8.21659629e-02, - 7.81897800e-01, 9.94561491e-01, 7.56646794e-01, 7.84591196e-01, - 5.47862271e-01, 2.07693027e-01, 6.61642364e-01, 5.46043761e-01, - 2.69485297e-01, 6.51595071e-01, 5.96015962e-01, 9.78866293e-01, - 1.12644756e-01, 2.08395393e-01, 2.39137730e-01, 4.55512794e-01, - 2.58054477e-01, 3.51078674e-01, 7.18697643e-01, 3.04283300e-01, - 8.85772053e-01, 1.07335595e-01, 1.11016666e-02, 4.66941811e-02, - 8.57695378e-01, 8.84085764e-01, 9.51419283e-01, 2.85808421e-01, - 2.94466675e-01, 8.95751848e-01, 9.51237288e-01, 8.70098323e-01, - 6.31355220e-01, 4.83351553e-01, 2.73303162e-01, 4.21021423e-01, - 5.56289349e-01, 3.09791015e-01, 9.89152931e-01, 8.30264199e-01, - 3.35968172e-01, 3.04151491e-01, 6.25620761e-01, 6.29068530e-01, - 1.09388475e-01, 5.44286763e-01, 2.06621700e-01, 5.85537407e-01, - 4.76106882e-01, 4.91342872e-01, 3.61321390e-01, 3.07561371e-01, - 1.56907444e-01, 1.49327630e-01, 2.86946091e-01, 2.57305975e-01, - 1.90511094e-01, 4.30100103e-01, 4.81990839e-02, 1.96229007e-02, - 9.39192833e-01, 1.70695395e-01, 8.68217041e-01, 1.42434092e-01, - 7.20000941e-01, 3.64174999e-01, 3.14028022e-01, 3.66794518e-01, - 1.97255141e-01, 5.01957854e-01, 7.50719103e-01, 6.84012437e-01, - 9.93919147e-01, 4.96941433e-01, 1.40961326e-01, 3.29951112e-01, - 9.64597524e-01, 2.04951224e-01, 3.69705513e-01, 4.11519663e-01, - 2.24723664e-01, 5.16087119e-01, 6.19955216e-01, 6.45240753e-02, - 3.77989995e-01, 1.87488656e-01, 7.37072960e-01, 1.94733439e-01, - 8.84650393e-01, 4.85073667e-01, 3.30942322e-01, 8.45970216e-01, - 1.85874456e-01, 3.95400662e-01, 9.42358280e-01, 7.48086224e-01, - 7.66473481e-01, 4.66850330e-01, 7.66936431e-01, 9.45319467e-01, - 2.58343803e-02, 2.19800750e-01, 5.19807098e-01, 8.26417654e-01, - 2.88910925e-02, 8.18651406e-01, 6.08262251e-01, 1.52200977e-01, - 5.16417506e-01, 8.59279352e-01, 5.24398933e-01, 1.04438632e-02, - 3.51627870e-01, 2.92104868e-01, 7.26154766e-01, 4.40209056e-01, - 7.43595262e-01, 7.36120016e-01, 4.66905976e-01, 4.99198690e-01, - 8.66496044e-01, 5.07439810e-01, 8.45398854e-01, 3.99111687e-01, - 7.66914290e-01, 5.40475958e-01, 6.17083815e-02, 4.86618164e-01, - 8.90140414e-01, 7.74410339e-01, 2.57394735e-01, 1.34582552e-01, - 1.37913779e-01, 1.40711021e-01, 6.20421361e-01, 6.17049397e-01, - 3.91919124e-02, 5.63344778e-01, 9.71582320e-01, 4.78070735e-01, - 6.39489999e-01, 5.54851510e-01, 6.20847233e-01, 2.48655091e-01, - 1.12036306e-01, 3.58044253e-01, 2.40563526e-01, 6.73866370e-01, - 8.32916319e-02, 9.42617969e-01, 6.85175163e-01, 8.86257647e-01, - 9.03598607e-01, 1.12067722e-01, 5.83994162e-01, 2.09640837e-01, - 4.13083435e-01, 1.99729861e-01, 7.48709636e-01, 1.58800314e-01, - 9.90927520e-01, 6.17744652e-02, 9.22245437e-01, 4.00679715e-02, - 4.28910311e-02, 6.32849146e-01, 2.89661878e-01, 4.46577741e-02, - 6.69896933e-01, 8.61051905e-01, 4.95476982e-01, 3.65595473e-01, - 7.01348878e-01, 1.22944294e-01, 6.45093371e-01, 4.81853573e-01, - 3.06177165e-01, 1.33241038e-01, 6.74666644e-01, 5.24154249e-01, - 4.20615272e-01, 1.01289416e-01, 8.84843584e-01, 8.14617259e-01, - 5.44945190e-01, 9.46511161e-01, 2.86147551e-01, 7.75739380e-01, - 5.54025247e-01, 5.91516168e-01, 7.41019496e-01, 3.39481973e-01, - 5.93373252e-01, 8.91760043e-01, 7.66931733e-01, 9.60071640e-01, - 5.68491119e-01, 7.27415296e-01, 3.10274385e-01, 2.48576743e-01, - 2.97305018e-01, 9.35289052e-01, 1.18540593e-01, 3.33102524e-02, - 3.63421806e-01, 7.47599050e-01, 2.61003865e-01, 3.51395142e-01, - 2.71370493e-01, 1.30290514e-01, 3.67409777e-01, 6.94999340e-01, - 3.50246710e-01, 4.40475356e-01, 4.83887311e-01, 6.70694419e-02, - 7.45450089e-01, 9.33630210e-01, 4.84844933e-01, 2.27515375e-01, - 5.20061854e-01, 5.66589164e-01, 5.46473362e-01, 8.55681458e-01, - 4.75649398e-02, 1.76488156e-01, 8.01700086e-01, 5.54733265e-01, - 9.87897914e-01, 5.45297384e-01, 4.03127520e-01, 9.62811661e-02, - 9.84187447e-01, 1.48308439e-01, 5.19639256e-01, 8.54746173e-01, - 5.49394002e-01, 8.03920086e-01, 5.01094073e-02, 7.31640681e-01, - 9.96655364e-01, 5.28259093e-01, 3.53773424e-01, 3.30416526e-01, - 7.28755138e-01, 5.00799785e-02, 6.21256958e-01, 9.76905213e-01, - 7.31860484e-01, 6.70918180e-01, 8.88697690e-01, 2.25997409e-01, - 8.61316842e-01, 8.34051782e-01, 5.61456480e-02, 5.05870572e-01, - 2.43314209e-01, 9.79258153e-01, 9.84103549e-01, 9.49817330e-01, - 5.22339401e-01, 1.75281414e-01, 1.27118190e-01, 8.34684239e-01, - 8.78523544e-02, 6.31105173e-01, 6.88690954e-01, 8.86817787e-01, - 4.24203485e-01, 6.18690633e-01, 8.58499444e-01, 3.40699490e-01, - 4.09048047e-01, 5.28199962e-01, 8.68438128e-01, 6.76980326e-01, - 9.96602335e-02, 6.35910470e-01, 2.02782704e-01, 1.34407251e-01, - 4.33024477e-01, 5.55471376e-01, 8.96482906e-01, 9.81521658e-01, - 9.28311782e-02, 9.36185775e-01, 3.36119211e-01, 5.90722090e-01, - 9.57876633e-02, 8.86488186e-01, 5.88546129e-01, 2.68689883e-01, - 7.65628884e-01, 5.17093745e-01, 3.27562280e-02, 4.46403474e-01, - 1.18580286e-01, 7.60833006e-02, 4.26251283e-01, 4.07476469e-01, - 8.07665335e-01, 6.70887688e-01, 6.81027151e-01, 3.16472677e-01, - 8.04942212e-01, 4.67548015e-01, 8.57818737e-01, 3.54376386e-01, - 3.87257380e-01, 3.96796899e-01, 6.07198026e-01, 9.84424697e-01, - 7.17794237e-01, 4.17304670e-02, 3.06700354e-01, 1.06816213e-01, - 3.62244493e-02, 5.96704126e-01, 6.23022199e-01, 8.63719677e-01, - 9.77772101e-01, 1.60840381e-01, 6.67476766e-01, 6.89678502e-01, - 9.78919114e-01, 2.98506375e-01, 3.73451890e-01, 2.79166438e-01, - 5.12995093e-01, 6.52845350e-01, 1.36708802e-01, 5.26858830e-02, - 7.91953105e-02, 4.10402396e-01, 6.85485684e-02, 9.16645020e-01, - 9.53487860e-01, 5.58362475e-01, 9.55041712e-01, 2.12343000e-01, - 2.09592841e-01, 5.77764894e-01, 7.55958181e-01, 3.97197079e-01, - 2.86547859e-01, 8.08694338e-01, 8.11330240e-01, 8.07997388e-02, - 6.02588256e-02, 3.58090677e-01, 6.31696898e-01, 7.25765761e-01, - 3.03867973e-01, 5.22208307e-01, 5.95113511e-01, 1.93917248e-01, - 6.93336484e-01, 4.68945831e-01, 5.71711340e-01, 4.65814532e-02, - 4.17931405e-01, 5.58218729e-01, 2.05405733e-01, 4.26406104e-01, - 2.55672483e-01, 8.50783826e-01, 8.41007957e-01, 2.90479497e-01, - 9.37725770e-01, 5.97105822e-01, 9.38180993e-01, 8.04185991e-01, - 8.78757367e-01, 7.97791945e-02, 2.54571978e-01, 7.33486785e-01, - 2.72100542e-01, 1.80360266e-01, 9.18105933e-01, 5.98155782e-01, - 9.57288341e-01, 2.79165869e-01, 9.51533064e-01, 6.45709886e-01, - 3.45390961e-01, 1.06156187e-01, 2.65540209e-01, 7.81212006e-01, - 6.13245340e-01, 2.69448654e-01, 5.59184842e-01, 6.78933623e-02, - 3.72053972e-01, 8.39822146e-01, 6.96559208e-01, 5.69445313e-01, - 1.94521445e-01, 2.99575456e-01, 7.14622666e-01, 2.58761360e-01, - 2.98778925e-01, 8.88073102e-01, 8.38053457e-01, 6.34929822e-01, - 8.29036472e-01, 6.72925777e-01, 3.94432278e-01, 4.61465287e-01, - 1.01100142e-01, 3.65136758e-01, 7.00952009e-01, 8.83561378e-01, - 3.66132754e-01, 5.09617437e-01, 1.28240885e-01, 9.05218645e-01, - 6.34551163e-01, 4.82098991e-01, 4.30733341e-01, 4.57745273e-01, - 5.80988446e-01, 7.58945533e-01, 5.21329399e-01, 4.41800584e-01, - 9.10839776e-02, 2.85592792e-01, 3.65260118e-01, 8.20410633e-01, - 9.51834125e-01, 7.26481208e-01, 6.46535207e-01, 4.60471555e-01, - 5.70667102e-01, 4.65408689e-01, 6.79807669e-01, 4.12960878e-01, - 6.01566393e-02, 4.41279309e-01, 8.57785159e-01, 1.94541490e-01, - 5.71581150e-01, 1.00558574e-01, 9.13180656e-01, 7.40378183e-01, - 2.79671457e-03, 2.28238515e-01, 8.54025954e-02, 2.25996397e-01, - 6.01997716e-01, 6.68228468e-01, 8.29994413e-01, 4.45582014e-02, - 8.33229016e-01, 9.68124455e-02, 6.45213939e-02, 9.08902320e-01, - 6.38630530e-01, 6.49904305e-01, 6.70210551e-01, 1.39084935e-01, - 6.53865487e-01, 3.72781167e-01, 9.11734645e-01, 3.92019562e-01, - 1.64879257e-01, 4.34820447e-01, 1.15044546e-02, 6.08003611e-01, - 3.81915126e-01, 4.46509769e-01, 5.72206499e-01, 4.85417514e-01, - 9.47774157e-01, 6.45287203e-01, 5.73971320e-01, 6.30085523e-01, - 6.37175073e-01, 1.57243264e-01, 9.68008267e-01, 6.03855918e-01, - 3.18754354e-01, 7.51607577e-01, 5.33013189e-01, 1.76648331e-01, - 5.42004463e-01, 1.05083006e-01, 4.80024812e-01, 5.53574557e-01, - 6.92947928e-01, 6.07564794e-02, 5.24270448e-01, 7.67120242e-01, - 1.72192574e-01, 6.35344204e-01, 2.64153698e-01, 8.42507593e-01, - 7.12767721e-01, 1.87450704e-01, 2.35616309e-01, 5.14739313e-01, - 7.04592123e-01, 2.49750362e-01, 4.85957579e-01, 9.30340995e-01, - 1.06283711e-01, 2.86754792e-01, 8.41251316e-01, 8.44712181e-01, - 7.57821474e-01, 5.22651716e-03, 4.32943870e-01, 9.26185554e-01, - 9.21796029e-01, 7.80535685e-01, 8.60970172e-02, 6.67827266e-01, - 6.64218856e-01, 3.57040990e-01, 3.61147185e-01, 9.08323924e-01, - 1.21250966e-01, 4.18836858e-02, 5.65714227e-01, 6.34819777e-01, - 6.65300013e-01, 2.80393985e-01, 3.12632326e-01, 7.93204664e-01, - 7.28994032e-01, 3.61832217e-01, 3.77784224e-01, 8.48436301e-01, - 8.43843665e-01, 2.14772052e-02, 4.65146482e-01, 7.59322206e-01, - 5.70665884e-01, 6.69850020e-01, 5.56189734e-01, 4.06630022e-01, - 4.60067954e-01, 1.20587913e-01, 4.92001607e-01, 9.52827962e-01, - 9.60397049e-01, 4.95977104e-01, 7.33706091e-01, 6.70250679e-01, - 1.36700477e-01, 1.37437503e-01, 9.89505781e-01, 9.20815652e-01, - 2.30390726e-01, 4.76175819e-02, 9.14609445e-01, 2.57292849e-01, - 9.15615749e-01, 4.10536833e-01, 2.75390187e-01, 3.42322189e-01, - 3.91511449e-01, 8.67368474e-01, 8.26312958e-01, 7.63415700e-01, - 2.58686841e-01, 9.01702644e-01, 9.04908731e-01, 4.82065073e-01, - 1.03740180e-01, 8.06393032e-01, 4.96334360e-01, 8.66705044e-01, - 8.41035301e-01, 4.59245421e-01, 7.19638625e-01, 8.14396479e-01, - 5.00324014e-01, 9.92023914e-01, 6.85847807e-01, 4.27823386e-01, - 9.80807153e-01, 1.84865464e-01, 5.22785893e-01, 8.68816197e-02, - 5.11839974e-01, 5.59566739e-01, 7.45268286e-02, 6.48721621e-03, - 3.12850372e-01, 9.98760486e-01, 7.91749218e-01, 8.56771435e-01, - 1.28139487e-01, 1.55746956e-01, 9.38488406e-01, 7.83873607e-01, - 1.70765544e-01, 3.92917094e-01, 7.86478733e-02, 9.39939963e-01, - 4.04823396e-01, 9.63631826e-01, 2.33684171e-01, 1.45599454e-01, - 8.42988117e-01, 7.06669576e-01, 6.13829681e-01, 8.94624130e-01, - 2.65020774e-02, 2.06745718e-01, 7.28843723e-01, 3.96858772e-01, - 7.10437357e-01, 4.28819478e-01, 6.90097008e-01, 2.93836406e-01, - 4.40132561e-01, 3.96220698e-01, 1.06889738e-01, 6.64587351e-01, - 5.06934655e-01, 8.93421184e-01, 5.63637256e-01, 6.50586965e-01, - 4.32608624e-03, 3.36838073e-01, 8.60998960e-01, 2.69122592e-01, - 5.76901464e-01, 2.62489938e-01, 2.54987131e-03, 8.12978251e-01, - 2.68082894e-01, 1.63100920e-01, 5.74022218e-01, 6.41915267e-01, - 8.51314008e-01, 2.26402162e-02, 4.16961267e-01, 4.48483938e-01, - 3.52232294e-01, 9.02376305e-01, 8.96245403e-01, 3.15139031e-01, - 1.46404487e-01, 6.52764635e-01, 4.98410494e-01, 6.06476931e-01, - 6.43849062e-01, 9.53659512e-01, 8.29986765e-01, 9.36170797e-01, - 3.99348041e-01, 8.26256061e-01, 6.52409968e-01, 8.49345512e-01, - 9.05091417e-01, 3.96178917e-01, 1.90226900e-01, 4.90332203e-01, - 7.42068655e-01, 7.20034853e-01, 6.01824133e-01, 1.81833343e-01, - 7.42155490e-02, 6.85603289e-01, 6.47746988e-01, 5.52852451e-02, - 6.93039797e-01, 8.69586716e-01, 1.56173534e-01, 5.95549419e-01, - 3.41971782e-01, 2.26118015e-01, 1.34416933e-01, 8.09101198e-01, - 5.19329091e-01, 4.98251539e-01, 4.63284263e-01, 6.16748471e-01, - 1.39761723e-01, 3.60230928e-01, 6.25383043e-01, 8.39903117e-01, - 4.65301339e-03, 2.28299203e-01, 7.39651978e-01, 9.91730454e-01, - 1.09900127e-01, 6.58900635e-01, 9.11180110e-01, 3.72570172e-01, - 6.81599913e-01, 2.42758234e-01, 2.91759271e-01, 5.92133206e-01, - 2.51286527e-01, 6.26639818e-01, 6.61266604e-01, 9.38243714e-01, - 9.60017718e-01, 1.38758457e-01, 4.15637748e-01, 6.72614742e-01, - 9.57904387e-01, 9.48748760e-01, 1.71827837e-02, 1.11286643e-01, - 3.15264587e-01, 6.85756201e-01, 4.64689208e-01, 5.13260994e-01, - 6.55387332e-01, 1.90404579e-01, 8.00139451e-01, 3.00409874e-01, - 5.58878597e-01, 2.22624662e-01, 7.11959889e-02, 6.87531604e-01, - 7.06438026e-01, 9.70894668e-01, 9.36524819e-01, 4.33739916e-01, - 8.31902301e-01, 8.36172919e-01, 1.12783165e-01, 6.24975369e-01, - 7.14322210e-01, 1.82658851e-01, 1.13706381e-01, 5.96102043e-01, - 5.71046353e-01, 3.56880754e-02, 4.48309707e-01, 6.91587382e-01, - 1.35182425e-01, 9.22093091e-01, 6.98601630e-01, 8.71729365e-02, - 2.50610802e-01, 6.38924483e-01, 1.86582009e-01, 2.86284233e-01, - 7.23340048e-01, 4.23655245e-01, 7.45452670e-01, 1.50961783e-02, - 1.43868777e-02, 2.07912741e-02, 3.94027111e-01, 6.47843293e-01, - 2.26814780e-01, 6.55875964e-01, 5.32974120e-01, 2.75195311e-01, - 5.07378427e-01, 3.73241830e-01, 3.18936516e-01, 5.98220468e-01, - 5.93092306e-01, 8.09475495e-01, 4.32731482e-01, 5.87426294e-01, - 7.80897153e-01, 5.31074731e-01, 5.18550755e-01, 4.05415035e-01, - 4.75867532e-01, 7.73422452e-01, 5.79042614e-01, 9.04150829e-01, - 2.67491670e-01, 8.23507152e-01, 8.08249116e-01, 7.77469197e-01, - 7.77529212e-01, 1.72246226e-01, 7.67460799e-01, 4.02734542e-01, - 2.73710767e-01, 4.71453579e-01, 5.69932677e-01, 8.92723487e-01, - 4.30959730e-01, 4.02839086e-01, 4.09902108e-02, 6.02722671e-01, - 5.92897409e-01, 4.43426279e-02, 7.31285595e-01, 7.17330356e-01, - 3.53106544e-01, 1.79783435e-01, 8.79670838e-01, 5.12861702e-01, - 6.61813435e-01, 6.42140967e-01, 6.09253614e-01, 5.00121046e-01, - 3.32729381e-01, 9.92718493e-01, 9.23990928e-01, 1.75163289e-01, - 2.40720996e-01, 4.11267054e-01, 9.78038996e-01, 1.30053190e-01, - 3.46751261e-01, 7.28563708e-01, 6.99494900e-01, 2.94433035e-01, - 1.15144256e-01, 6.93726407e-04, 3.18530826e-01, 6.01677485e-01, - 7.97612355e-01, 8.72316786e-01, 5.20291828e-01, 4.99290831e-01, - 5.70823182e-02, 9.22153637e-01, 4.90522698e-01, 9.74276273e-02, - 7.98290462e-02, 8.70595211e-01, 4.10726019e-01, 7.52595908e-01, - 4.35924653e-01, 2.65245854e-01, 5.89498790e-01, 4.03024022e-01, - 9.05063092e-01, 6.58875081e-01, 4.57839861e-01, 8.49476738e-01, - 8.67706721e-01, 9.63146401e-01, 8.20582789e-01, 8.61768492e-01, - 4.13925448e-01, 3.47244472e-02, 6.50800903e-01, 5.65590195e-01, - 1.13640789e-01, 6.27489991e-01, 2.14319671e-01, 6.52087982e-01, - 2.22071566e-01, 5.76874407e-01, 1.82464938e-01, 9.18942763e-01, - 1.40479690e-02, 6.66479302e-01, 2.50660160e-01, 3.82100787e-01, - 8.38799846e-03, 7.06090941e-01, 3.34950083e-01, 3.53977522e-01, - 6.87152459e-01, 8.53360880e-02, 5.23940945e-01, 4.47105021e-02, - 7.26347519e-01, 4.01460539e-01, 3.98645845e-02, 1.34938348e-01, - 9.84858690e-01, 6.90798927e-01, 8.45220242e-01, 2.40055231e-01, - 7.17003140e-01, 4.78686180e-01, 8.11464420e-01, 3.96921628e-01, - 8.42381350e-01, 7.83277811e-01, 8.26923982e-01, 1.52482944e-01, - 6.46357627e-01, 8.13412855e-01, 6.19059315e-01, 2.16781326e-01, - 8.93422041e-01, 8.23973622e-01, 7.27752196e-01, 3.21930540e-01, - 6.17739245e-01, 2.86744482e-01, 7.62810746e-01, 6.16176876e-01, - 5.34506182e-02, 2.56641000e-01, 4.62871351e-01, 9.01510093e-02, - 5.54161033e-01, 5.36226827e-01, 3.29524889e-01, 5.67120678e-01, - 1.68729553e-01, 6.03179243e-01, 2.63268982e-01, 5.99452285e-01, - 4.73746174e-02, 3.31660338e-01, 7.90031189e-01, 8.51962590e-01, - 5.42750770e-02, 6.49115583e-02, 1.16106045e-01, 8.62547538e-01, - 4.87380008e-01, 9.91667455e-01, 5.49058431e-02, 6.56743598e-01, - 3.52146483e-01, 1.96582821e-01, 8.70906396e-01, 9.43439930e-01, - 6.20690320e-01, 8.13905835e-01, 5.99777143e-02, 8.07295628e-01, - 6.98585463e-01, 6.55295416e-01, 1.79335565e-02, 8.66528575e-01, - 7.95448787e-01, 2.25760695e-01, 6.94883365e-01, 9.04899709e-02, - 2.75857039e-01, 1.47161028e-01, 8.15856204e-01, 4.57271280e-01, - 2.95413290e-01, 7.19273162e-01, 9.40014496e-01, 1.32948359e-02, - 8.57128881e-01, 8.66565562e-01, 2.54646785e-01, 8.23004534e-01, - 2.47711346e-01, 6.15561070e-01, 7.86174065e-01, 3.69029737e-01, - 3.71685156e-01, 9.26807357e-01, 5.62044299e-01, 9.24537106e-01, - 1.35524199e-01, 4.07331428e-01, 7.33903613e-02, 2.77728962e-01, - 8.28676221e-01, 3.58925509e-02, 7.23369346e-01, 7.96285963e-01, - 3.92078280e-01, 7.98968267e-02, 4.36683114e-01, 2.27817009e-01, - 1.51712739e-01, 9.57798208e-01, 4.31912959e-01, 7.11489092e-01, - 8.53141123e-01, 3.78735149e-01, 6.41407298e-01, 6.19329379e-01, - 5.03432538e-01, 1.07157313e-01, 7.47780087e-02, 6.09398498e-02, - 9.71694060e-02, 3.10061383e-01, 1.68850018e-01, 6.44025987e-01, - 2.25634210e-01, 7.18376867e-01, 4.33708643e-01, 5.13621857e-02, - 6.16812142e-01, 3.98266620e-01, 9.64984922e-01, 1.09613995e-01, - 9.58991350e-01, 4.56004266e-01, 1.32965923e-01, 5.86888514e-01, - 7.48678592e-01, 2.19005065e-01, 3.56717472e-01, 7.70376136e-04, - 7.07378863e-01, 2.23984814e-02, 7.87092117e-01, 1.96659228e-01, - 4.57087727e-01, 6.87352114e-01, 2.19573622e-01, 5.49523635e-01, - 8.11984182e-01, 8.14483356e-01, 8.40953324e-01, 2.31454815e-01, - 2.78947927e-01, 2.78532957e-01, 7.10040268e-01, 8.30253191e-01, - 2.99209924e-01, 8.25882477e-01, 5.81379113e-01, 4.25770940e-01, - 8.06465501e-01, 7.50395996e-01, 1.18149115e-01, 2.91278649e-01, - 1.89798539e-01, 1.72768577e-01, 3.60267108e-02, 2.36939560e-01, - 7.96462944e-01, 6.64851749e-01, 4.06920400e-01, 1.24022211e-01, - 2.14890418e-01, 2.86479104e-01, 9.38359711e-01, 2.66248338e-01, - 3.14441258e-01, 4.33500099e-01, 8.21670967e-01, 3.50262912e-01, - 2.04668675e-02, 3.15114998e-01, 9.35173352e-01, 1.20688242e-01, - 9.02704706e-01, 4.44179968e-01, 1.62498781e-01, 8.24454688e-01, - 2.45545919e-01, 1.59717687e-01, 5.78075551e-01, 1.09240697e-01, - 3.33500682e-01, 2.54720295e-02, 1.24460080e-01, 3.65858791e-01, - 3.81253425e-01, 5.75265921e-01, 2.41440154e-01, 9.31528781e-01, - 2.61488038e-01, 4.55649167e-02, 7.79076636e-01, 8.90405817e-01, - 8.57219388e-01, 5.19888211e-01, 2.52734597e-01, 2.95547886e-02, - 6.65540312e-01, 8.53412324e-01, 8.73143550e-01, 9.34336646e-01, - 8.76177549e-01, 6.06182354e-01, 1.87905206e-01, 7.77081995e-01, - 7.94047446e-01, 9.59312088e-01, 4.26727654e-01, 7.50592762e-01, - 2.84645729e-01, 3.13015951e-01, 2.35860393e-01, 3.36604974e-01, - 6.18830577e-01, 5.60224026e-01, 6.91123848e-01, 8.83730449e-01, - 3.08063944e-02, 2.00897430e-01, 7.92166250e-01, 4.62901075e-01, - 8.34055002e-01, 1.97822223e-01, 9.12072314e-01, 4.30890577e-01, - 4.10218302e-01, 4.67830747e-01, 5.13951081e-03, 5.06239755e-01, - 2.84006807e-01, 3.30818338e-01, 7.04589489e-01, 5.08295792e-01, - 3.66481532e-01, 4.15192062e-01, 9.11199460e-01, 8.03988404e-01, - 6.51728248e-01, 9.77564881e-01, 2.55171224e-01, 1.44861629e-01, - 9.45601776e-01, 9.69918541e-01, 5.65384668e-01, 8.07950482e-02, - 3.93608002e-03, 8.99411813e-01, 5.83092071e-01, 9.12930438e-01, - 3.71436091e-01, 3.72860089e-01, 4.63617045e-01, 2.64695052e-01, - 9.57153104e-01, 7.43478360e-01, 2.71932076e-01, 6.36119597e-01, - 7.06178272e-01, 1.72359802e-01, 5.21867902e-01, 4.14521502e-01, - 3.54719483e-01, 1.68309128e-01, 8.55739507e-01, 6.77478610e-01, - 8.17654590e-02, 5.22710842e-01, 8.44737984e-01, 8.69571251e-01, - 8.75292234e-01, 9.80920051e-01, 1.80551918e-01, 5.40994128e-01, - 5.32648563e-01, 3.00903740e-02, 7.70135893e-01, 9.06214482e-01, - 3.99306651e-01, 3.41822929e-01, 9.04735490e-01, 5.49568872e-01, - 4.17715366e-01, 3.13710968e-01, 1.61705444e-01, 7.24025164e-01, - 5.01121517e-01, 8.01219341e-01, 1.53910240e-01, 2.99403630e-01, - 7.08788284e-01, 5.64309033e-01, 4.97339915e-01, 3.57959876e-01, - 7.83259879e-01, 3.38291492e-01, 1.47240714e-01, 9.43943730e-01, - 8.50315041e-01, 7.67558546e-01, 9.47200891e-01, 2.93793939e-01, - 2.94060144e-01, 9.97988891e-01, 8.42805794e-01, 1.44095859e-01, - 9.39273174e-01, 2.11441062e-01, 7.71253610e-01, 3.95114614e-01, - 5.03108637e-02, 2.82149324e-01, 9.44608677e-01, 6.09752464e-01, - 7.08546698e-01, 6.97337208e-01, 6.94653682e-01, 8.78376350e-01, - 1.95380091e-01, 5.08193561e-01, 8.79038037e-01, 3.08200472e-01, - 4.78457359e-01, 4.37728198e-01, 2.11784455e-01, 4.76265202e-01, - 6.51236233e-01, 6.72173626e-02, 5.78136033e-01, 5.88263347e-01, - 7.75432270e-01, 1.05802542e-01, 3.44473911e-01, 2.35196170e-01, - 1.04339004e-01, 6.81826438e-01, 6.32694726e-02, 1.54430645e-01, - 8.17967462e-01, 4.90666673e-01, 4.06443180e-01, 9.75676332e-01, - 3.71438259e-01, 7.59444843e-02, 9.62782532e-01, 1.27783244e-01, - 8.65498744e-01, 9.87630640e-01, 3.50645096e-01, 2.01057201e-01, - 9.78856260e-01, 9.36097695e-01, 5.90743408e-01, 8.36568198e-02, - 9.56506298e-01, 5.44310183e-01, 4.73459002e-01, 7.97335105e-01, - 9.68370787e-01, 5.97292298e-01, 5.32022558e-01, 5.15198787e-01, - 6.48835202e-02, 4.21703557e-01, 2.67196159e-01, 3.35475351e-01, - 2.00120831e-01, 3.79852128e-01, 8.93303729e-01, 1.57907903e-01, - 1.27314971e-01, 4.99153754e-01, 5.46169883e-01, 3.97852611e-01, - 7.74234552e-01, 6.86181238e-01, 5.92067547e-01, 2.13976671e-01, - 3.57346244e-01, 1.26608839e-01, 4.79637984e-01, 6.06959580e-01, - 8.42021307e-01, 2.73088038e-01, 2.59736264e-01, 5.97240469e-01, - 7.56535007e-01, 5.03662794e-01, 4.54303003e-01, 4.54209500e-01, - 9.98163283e-01, 6.79845235e-01, 4.66081937e-01, 5.30574321e-01, - 7.89516493e-01, 2.14929347e-01, 5.30881721e-01, 2.29671115e-01, - 4.40878726e-01, 5.16183706e-01, 7.18662096e-01, 7.41166660e-01, - 2.25848031e-01, 6.22182244e-01, 8.30108206e-01, 2.91599945e-01, - 6.38300120e-01, 3.27744620e-02, 1.31241405e-01, 7.41345648e-01, - 5.23126125e-01, 7.21240929e-01, 6.49794993e-01, 4.49875268e-01, - 2.17249622e-01, 2.96302227e-01, 4.98081638e-01, 1.00481368e-01, - 1.80071913e-01, 2.57772697e-01, 2.48911947e-01, 4.74891198e-01, - 9.13604032e-02, 3.86341099e-01, 2.65009566e-01, 5.56396603e-01, - 2.26041119e-01, 2.06620400e-01, 2.54210154e-02, 6.01557575e-01, - 3.16068190e-01, 2.56070796e-01, 2.91399995e-01, 8.13237606e-01, - 7.28457314e-01, 1.69092225e-01, 4.47953174e-02, 7.21206133e-01, - 4.57683763e-01, 4.12995321e-01, 1.70304098e-01, 8.82111991e-01, - 1.16086028e-01, 9.72298671e-01, 4.15413491e-01, 4.59158446e-01, - 2.76205668e-02, 8.58813445e-01, 1.30998083e-01, 2.46251335e-01, - 4.30752133e-02, 5.75952486e-02, 5.87763021e-01, 5.51387173e-01, - 9.58273129e-01, 6.32428023e-01, 6.21945101e-01, 8.51680344e-01, - 9.86730184e-01, 5.59471038e-01, 7.28549450e-02, 1.32624270e-01, - 2.89986946e-01, 8.78814765e-01, 6.81090440e-01, 1.27247254e-01, - 9.20827861e-01, 8.92096743e-01, 2.13786647e-01, 9.15466928e-02, - 5.84119122e-01, 3.63358390e-01, 4.36501249e-01, 3.80860682e-01, - 9.04810017e-01, 3.93371696e-02, 3.92564829e-01, 6.78766045e-01, - 3.43966776e-01, 1.40013844e-02, 8.35446088e-01, 2.99624041e-01, - 5.40855478e-01, 7.09795470e-01, 2.95056458e-01, 1.68499069e-01, - 5.21405167e-01, 4.89000157e-02, 5.36086729e-01, 1.94189685e-01, - 1.91137583e-01, 8.72211181e-01, 9.75342603e-01, 5.62204790e-01, - 2.40590898e-01, 9.34409629e-02, 3.35948017e-01, 5.36830619e-01, - 7.78632734e-01, 8.49227239e-01, 7.29960539e-01, 9.25858936e-01, - 6.86792213e-01, 2.57330211e-02, 6.73464822e-01, 9.20451112e-02, - 7.48991259e-01, 2.63769336e-01, 9.04201533e-01, 3.41507439e-01, - 8.29063390e-02, 9.12740235e-01, 9.44873474e-01, 6.52539431e-01, - 5.84702825e-02, 7.72132232e-01, 4.83548547e-01, 4.78145422e-01, - 3.43788218e-01, 9.81665739e-02, 4.69355255e-01, 4.61421354e-01, - 4.33676613e-01, 5.92252267e-01, 1.66725150e-01, 1.42115710e-02, - 3.64864896e-01, 2.89136999e-01, 7.79742108e-01, 9.71816674e-01, - 3.00190426e-01, 6.12281938e-01, 3.97577553e-01, 3.68165281e-01, - 4.46587312e-02, 7.01571977e-01, 4.06758097e-01, 6.44809109e-01, - 8.03909756e-01, 1.85778263e-01, 5.98382141e-01, 9.00174123e-01, - 2.86789045e-01, 6.63768777e-01, 2.86744638e-02, 3.06127946e-01, - 1.04728939e-01, 3.92302773e-02, 4.99797957e-01, 4.92956778e-01, - 1.05184878e-01, 2.91791616e-01, 3.12224671e-01, 8.46566754e-01, - 7.75013707e-01, 9.39070916e-01, 2.05915592e-01, 7.30897045e-01, - 7.27113833e-01, 2.93886565e-02, 2.99872224e-01, 2.75341097e-01, - 5.52144238e-01, 3.07481568e-01, 5.23792167e-01, 9.66228012e-02, - 8.49650067e-01, 3.79934821e-01, 9.30389764e-01, 9.84831894e-01, - 6.42343931e-01, 6.97611434e-01, 5.83350063e-01, 6.88610584e-01, - 5.77306162e-01, 3.67916572e-01, 2.50165214e-01, 5.12377327e-01, - 8.19027386e-01, 3.32637100e-01, 8.36917368e-01, 8.26537522e-01, - 1.54941575e-01, 4.61731515e-01, 5.20444401e-02, 1.62627427e-01, - 9.35232397e-01, 2.56387389e-01, 1.49757552e-01, 4.60006427e-01, - 1.97147987e-01, 8.57012838e-01, 9.80435141e-01, 3.03395261e-01, - 9.18672759e-02, 7.25840396e-01, 6.61295266e-01, 9.20092348e-02, - 9.07829336e-01, 4.45778564e-01, 2.24167711e-02, 3.88048710e-01, - 7.38708671e-01, 4.90069797e-01, 4.50536793e-01, 9.28350198e-01, - 6.66497382e-01, 1.10673639e-01, 2.95684591e-01, 2.64281339e-03, - 8.94414913e-01, 5.79935459e-01, 5.68542757e-01, 3.23272744e-01, - 8.76191781e-01, 2.50696551e-01, 5.48297475e-01, 6.42798572e-01, - 4.45587812e-01, 1.26885546e-01, 9.82168265e-01, 4.99123036e-01, - 8.29585102e-01, 2.16470117e-01, 6.61870790e-01, 5.01013865e-01, - 1.41935726e-01, 6.03628336e-01, 8.82142165e-02, 4.78199237e-01, - 3.40033037e-01, 1.65990221e-01, 9.70489072e-02, 5.30353065e-01, - 8.16816576e-01, 5.65825329e-01, 3.83517399e-01, 3.77309615e-01, - 3.97097266e-02, 6.28892651e-01, 2.12768506e-01, 8.53513250e-01, - 5.40896585e-01, 8.83523556e-01, 9.23658221e-01, 2.73542774e-01, - 8.94399286e-01, 8.38876783e-01, 7.70029834e-01, 9.08151992e-01, - 6.49728255e-02, 3.93770462e-02, 6.10108759e-01, 3.57220979e-01, - 8.07951886e-01, 4.73599445e-01, 6.95481583e-01, 1.44957699e-01, - 6.99887460e-01, 3.86235814e-01, 3.27318645e-02, 6.38764496e-01, - 9.25341875e-01, 3.16482354e-01, 1.05084029e-01, 2.60832353e-01, - 9.38619893e-01, 6.65865187e-01, 5.54712475e-01, 6.40106319e-01, - 1.97921823e-01, 7.44039621e-01, 6.07216315e-02, 6.41884028e-01, - 4.35102032e-01, 9.11106397e-01, 2.50588312e-02, 8.82784921e-01, - 9.07660615e-01, 1.12421168e-01, 2.85785527e-01, 7.53092562e-01, - 8.67722134e-01, 1.77992791e-01, 8.86101977e-01, 7.23131731e-01, - 7.55194824e-01, 2.16715237e-01, 1.80614382e-02, 4.66866697e-02, - 2.87435942e-01, 9.66480285e-01, 2.00927646e-01, 5.38945564e-01, - 4.80477321e-01, 3.14560444e-01, 2.14885782e-01, 3.25387687e-01, - 2.61608590e-01, 3.02017086e-01, 7.79909811e-01, 5.63452147e-01, - 3.59273858e-01, 9.36159171e-01, 1.03753034e-01, 3.66360501e-01, - 7.93926004e-01, 8.71701388e-01, 3.52629018e-01, 6.48416964e-01, - 4.91614388e-01, 4.70602494e-02, 6.72923307e-01, 5.30716631e-01, - 7.18770207e-01, 1.85149178e-01, 2.17639128e-01, 8.04818215e-01, - 9.98571564e-01, 3.08143259e-01, 3.36437181e-02, 5.53807556e-01, - 1.57458763e-01, 8.82609910e-01, 1.37909232e-02, 1.54247552e-01, - 6.01978996e-01, 4.13324239e-01, 1.83160784e-01, 7.77498873e-01, - 7.69972836e-01, 2.80718639e-01, 8.67750144e-01, 7.45372160e-01, - 5.17538648e-02, 7.98899230e-03, 9.43646439e-01, 5.04539071e-01, - 4.22340933e-01, 6.47224843e-01, 7.90390038e-01, 8.03536527e-01, - 6.59696029e-01, 8.53998204e-01, 2.43210904e-01, 6.71668693e-01, - 7.49375053e-02, 8.46519701e-01, 3.06491907e-02, 9.08189570e-01, - 3.64337923e-03, 9.55893813e-01, 6.98856097e-01, 8.12786496e-02, - 9.02132505e-01, 6.68469737e-01, 3.20848151e-01, 5.89661413e-01, - 3.85233532e-01, 7.58205297e-01, 8.82752853e-01, 4.98135073e-01, - 5.77447572e-01, 4.95788529e-01, 2.93822011e-01, 9.43635846e-01, - 2.34578907e-01, 1.64977369e-01, 4.90752169e-01, 6.27390300e-01, - 8.28991623e-01, 3.94846864e-01, 8.15233085e-01, 8.23697605e-01, - 5.41586080e-01, 6.79174489e-01, 2.27858081e-01, 1.08760915e-01, - 1.34133051e-03, 8.96360225e-02, 8.36224039e-01, 9.90714290e-01, - 5.58233066e-01, 2.90486840e-01, 3.00546337e-01, 7.42076199e-01, - 5.39029892e-01, 2.89840177e-01, 8.05718119e-01, 8.69912133e-01, - 6.92285486e-01, 7.34000342e-01, 5.94043756e-01, 1.46455220e-01, - 2.27343369e-01, 7.51514005e-01, 4.82879364e-02, 5.44419032e-01, - 9.85279914e-01, 2.81725016e-01, 8.41378605e-01, 9.65722155e-01, - 1.61083824e-01, 5.25033651e-01, 5.05583877e-01, 4.16334845e-01, - 4.14554379e-03, 4.97526373e-01, 8.22099480e-01, 8.21694881e-01, - 3.18252021e-01, 7.01441227e-01, 8.36172415e-01, 4.11720221e-01, - 1.28072502e-01, 6.24153675e-01, 6.37053014e-01, 3.74140377e-01, - 3.53752899e-01, 1.65317357e-01, 2.59173731e-01, 1.66553128e-01, - 2.52968461e-01, 9.55955395e-01, 2.28898534e-02, 6.22315794e-01, - 5.38891667e-02, 1.48180473e-01, 1.37973802e-01, 2.60853184e-01, - 8.43885067e-01, 7.72693953e-01, 2.67544307e-01, 1.24772775e-01, - 7.57828743e-01, 6.84671309e-01, 6.51416717e-01, 2.25225476e-01, - 5.99644998e-01, 6.23742940e-01, 4.65226860e-01, 7.42617559e-02, - 3.18807812e-01, 2.06616165e-01, 3.13234436e-01, 4.99518636e-01, - 1.67451459e-01, 7.45857271e-01, 3.12715793e-03, 2.55550479e-01, - 6.64680763e-01, 2.28871803e-01, 1.19109926e-01, 7.15723241e-01, - 9.60899663e-01, 9.19424722e-01, 5.21271098e-01, 3.44684774e-01, - 1.53259682e-01, 6.65628388e-01, 5.64016364e-01, 2.87863592e-01, - 9.32114634e-01, 3.72907079e-01, 2.59975286e-01, 2.20528399e-01, - 8.12307869e-01, 6.58696392e-01, 3.36726003e-02, 8.56292742e-01, - 3.30377051e-01, 1.15037016e-01, 3.05257404e-01, 8.15835231e-01, - 3.86912880e-01, 2.07869664e-01, 3.02098405e-01, 2.14780850e-01, - 5.33371352e-01, 2.47428352e-01, 7.18541981e-01, 4.99539269e-01, - 7.02894191e-01, 1.27824356e-02, 8.65178573e-01, 4.17767510e-01, - 8.47283685e-02, 9.26811574e-01, 4.70911192e-01, 6.53744614e-01, - 9.22223548e-01, 5.50378286e-01, 1.63336084e-01, 9.01243669e-01, - 5.33367769e-01, 1.33025745e-01, 7.24672708e-01, 9.26677761e-01, - 1.37741741e-01, 2.53674145e-01, 4.43532913e-01, 6.04275393e-01, - 8.10980498e-01, 3.01951089e-01, 5.71606807e-01, 4.60884411e-01, - 5.38174553e-01, 6.94037776e-01, 2.86668498e-02, 4.39302545e-01, - 8.80537506e-01, 1.03847589e-01, 6.91025662e-01, 5.39867949e-02, - 7.43812130e-01, 3.41867079e-01, 3.53884194e-01, 5.01176917e-01, - 2.41966124e-01, 8.63479192e-01, 5.12188305e-01, 9.62652290e-01, - 3.02663973e-01, 3.79710389e-01, 1.93096999e-01, 2.98392804e-01, - 6.65158415e-01, 2.30257025e-01, 2.32254475e-01, 6.30773700e-01, - 8.71043119e-01, 5.03747937e-01, 6.47165299e-01, 2.55509290e-01, - 6.26277610e-01, 6.84436254e-01, 6.61327462e-01, 5.19344809e-01, - 7.27386236e-01, 8.50418451e-01, 6.11660587e-01, 3.52985340e-01, - 2.55853355e-01, 6.18034771e-02, 8.81176575e-01, 7.62725355e-01, - 4.67846046e-02, 6.77907529e-01, 3.93293288e-01, 7.61837331e-01, - 6.00692301e-01, 8.20463128e-01, 4.01810788e-01, 3.92799420e-01, - 6.12399134e-02, 8.03344906e-01, 6.34622453e-01, 4.24438312e-01, - 9.31466256e-01, 8.80238066e-01, 4.37765311e-01, 7.74150877e-01, - 9.24357824e-01, 8.32156740e-01, 6.24222943e-01, 8.41977283e-01, - 9.12118804e-01, 3.09613720e-01, 9.87469304e-01, 2.88164994e-01, - 7.24177660e-01, 8.43235100e-01, 6.22194661e-01, 7.68060813e-01, - 9.77147590e-01, 5.81604755e-02, 8.36563098e-01, 4.61377172e-02, - 5.29668121e-01, 1.34262073e-01, 2.26428603e-02, 1.11809843e-01, - 9.68106178e-01, 9.25664505e-01, 8.77361713e-02, 1.36530070e-01, - 7.21646988e-01, 7.46253478e-01, 1.61322856e-01, 7.95322694e-01, - 1.45165654e-01, 3.58510534e-01, 4.21185727e-01, 5.16769947e-01, - 5.04217360e-01, 2.66574268e-02, 6.95362901e-01, 4.96669465e-01, - 1.20415111e-01, 7.42233024e-01, 7.01889607e-01, 3.30369888e-01, - 5.64318493e-01, 5.19393593e-01, 5.61280112e-01, 1.55156761e-01, - 5.25531465e-03, 4.45086259e-01, 4.46959192e-01, 6.22293459e-01, - 1.95734197e-02, 8.35799147e-01, 4.25423955e-02, 8.52137548e-01, - 9.04683534e-01, 2.08514879e-01, 7.07098565e-01, 7.91235629e-01, - 1.03469753e-01, 7.75504981e-01, 4.52246577e-01, 3.71105177e-01, - 7.63829919e-01, 9.09311995e-01, 4.13256276e-01, 7.19838382e-01, - 2.21534235e-01, 6.44141531e-01, 4.13230490e-01, 1.15878847e-01, - 7.26329167e-01, 9.21542392e-01, 4.71764789e-01, 4.84166337e-01, - 3.26162452e-01, 4.42979530e-01, 9.32492319e-01, 8.51938572e-01, - 5.54384532e-01, 2.90615280e-01, 8.77400798e-01, 8.53221556e-01, - 9.39244576e-01, 6.86344538e-01, 5.32078907e-01, 3.71292846e-01, - 5.30099610e-01, 9.96293913e-02, 1.37968707e-01, 5.37732455e-01, - 6.23351036e-01, 2.56327697e-01, 3.45032389e-01, 5.59168880e-01, - 1.45237793e-01, 1.14495397e-01, 9.76000934e-01, 4.67428646e-01, - 3.37262208e-01, 8.85711733e-01, 7.71257046e-01, 6.71469065e-01, - 3.97974314e-01, 1.30142737e-01, 4.59094357e-01, 7.84232017e-01, - 7.44570471e-01, 1.00520165e-01, 2.91126398e-01, 5.80811428e-01, - 8.98989550e-01, 9.71924608e-01, 6.88992551e-01, 9.58199656e-01, - 8.74014090e-01, 4.24236606e-01, 2.42656461e-01, 4.72488242e-01, - 9.73782147e-01, 2.37262785e-01, 9.61792445e-01, 1.48509803e-01, - 2.11629145e-01, 1.13366955e-01, 1.09012226e-01, 9.12223874e-01, - 1.03901653e-02, 1.75994433e-01, 1.19299892e-01, 4.25802629e-01, - 5.94867245e-01, 6.00679820e-01, 5.57465595e-01, 7.16316815e-01, - 7.96086599e-01, 4.54557691e-01, 9.19541313e-01, 5.19745199e-01, - 6.05278973e-02, 7.50201194e-01, 4.52662154e-02, 7.35166341e-01, - 1.18252067e-01, 9.67366805e-01, 3.68374237e-02, 1.74398383e-01, - 3.22099840e-01, 8.27640568e-02, 3.87862190e-01, 8.39137131e-01, - 9.53222586e-01, 3.68051022e-01, 9.41878539e-01, 2.82101961e-01, - 7.67362236e-01, 3.03702862e-01, 8.96289596e-01, 3.04775114e-01, - 5.88156814e-01, 3.09919097e-01, 4.28924143e-01, 7.15119820e-01, - 7.55110968e-01, 3.70591083e-02, 5.87197607e-01, 7.89893876e-02, - 5.40252492e-01, 8.19258213e-01, 7.65168758e-01, 2.31028033e-01, - 8.06317818e-01, 5.91819389e-01, 6.42716516e-02, 8.60469841e-01, - 5.02692652e-01, 4.72437214e-01, 2.36203583e-01, 7.62296393e-01, - 3.57835411e-01, 7.09380334e-01, 9.65324538e-01, 3.04279042e-01, - 5.77823199e-01, 5.70190089e-01, 4.35061545e-01, 3.67801208e-01, - 3.87011698e-01, 3.02008273e-01, 5.99756399e-01, 2.34647587e-01, - 5.49955533e-01, 4.46487501e-01, 1.29139222e-01, 5.59220781e-01, - 6.65959456e-01, 5.16564037e-01, 6.39020969e-01, 3.59645773e-01, - 2.67237084e-01, 3.92483439e-01, 7.20251303e-01, 8.63001241e-01, - 9.47696551e-01, 7.47728894e-01, 5.97450029e-01, 3.83325258e-01, - 6.04514023e-01, 4.51254363e-01, 8.26276392e-01, 2.62075544e-01, - 2.58475871e-01, 9.51365306e-01, 6.16443482e-01, 9.12852037e-01, - 3.85064508e-01, 5.41813300e-01, 3.50418370e-01, 7.37517327e-01, - 9.59418037e-01, 9.05967968e-01, 7.78601183e-01, 1.93422684e-01, - 6.01139805e-01, 9.47118395e-01, 1.88385509e-01, 3.62670265e-01, - 1.88461219e-01, 9.60773959e-01, 6.41737867e-02, 8.25966168e-01, - 4.26312177e-01, 8.64671182e-01, 3.68261080e-01, 6.52385028e-01, - 9.59641367e-01, 2.79162703e-01, 4.00129018e-02, 5.33289421e-01, - 5.79517144e-01, 4.69888725e-01, 8.62329920e-01, 8.29213446e-04, - 6.23181289e-01, 7.76862703e-01, 5.15074356e-01, 9.79800160e-02, - 1.92022733e-01, 6.05421866e-01, 4.85404683e-01, 1.08325254e-01, - 1.93562428e-01, 4.40610515e-01, 3.55265373e-02, 5.38674463e-01, - 9.06126831e-01, 3.29320226e-01, 6.27469097e-01, 2.85528996e-01, - 2.90995057e-01, 1.26319415e-01, 8.31754971e-01, 6.69290445e-01, - 1.81967153e-01, 8.57700587e-01, 9.53324230e-01, 3.32024211e-01, - 7.97160822e-01, 4.70926704e-01, 4.11445916e-01, 7.42050770e-01, - 8.79718589e-01, 9.23242653e-01, 7.59597129e-01, 4.51272989e-01, - 4.93825407e-01, 3.29752384e-01, 2.17108314e-01, 1.10581369e-01, - 4.57770565e-01, 5.25770748e-01, 4.96270443e-02, 3.46590494e-01, - 8.44889681e-01, 2.04066052e-02, 7.13399695e-01, 7.28892904e-01, - 9.11722119e-01, 7.19418931e-01, 9.38820810e-01, 8.82643881e-01, - 2.50480936e-01, 3.34922661e-01, 1.90869568e-02, 7.10956993e-01, - 1.68187616e-01, 2.92566933e-01, 8.80722338e-01, 2.48884250e-01, - 6.40592462e-01, 3.39448838e-01, 7.21217209e-01, 4.16597600e-01, - 7.48194041e-01, 2.10922462e-01, 3.15319332e-03, 3.55068429e-01, - 8.20362813e-01, 2.53063504e-01, 4.73371736e-01, 2.62233310e-01, - 6.53457288e-01, 8.13231968e-01, 5.44729597e-04, 7.61155354e-01, - 4.17665699e-01, 7.36800580e-02, 5.43074702e-01, 5.44393468e-01, - 5.49567448e-01, 4.15169048e-01, 1.78184367e-01, 8.80828989e-01, - 8.01608004e-01, 8.32633139e-01, 6.04199497e-01, 5.34469505e-01, - 8.14237761e-01, 6.76921805e-01, 6.56300841e-01, 5.14595454e-01, - 9.09174140e-01, 6.84625333e-02, 9.57183750e-01, 6.04097419e-01, - 5.82837816e-01, 7.74836246e-01, 2.44027401e-01, 9.54576179e-01, - 5.31266190e-01, 2.91350470e-01, 5.10250939e-01, 5.62910811e-01, - 9.08124579e-01, 9.54307715e-01, 3.15899550e-02, 9.57302766e-01, - 1.15290745e-01, 3.31393531e-02, 9.97250114e-01, 7.33386478e-01, - 5.48173901e-01, 2.27193248e-01, 1.57753098e-01, 4.41062677e-01, - 9.24626256e-01, 3.34686830e-01, 6.86687926e-01, 8.87207142e-01, - 5.83273451e-02, 2.17598580e-02, 6.70365769e-02, 4.96095197e-01, - 5.46416072e-01, 2.62197529e-01, 5.27047144e-01, 2.70111911e-01, - 8.67426697e-01, 7.93274806e-01, 6.52472851e-01, 7.74711779e-02, - 6.63840539e-01, 6.23164056e-01, 7.96354100e-02, 7.89341247e-01, - 3.67328964e-01, 9.71861742e-01, 1.59700346e-01, 9.32195911e-01, - 1.62680292e-01, 6.19043742e-01, 7.22931729e-01, 7.28505258e-01, - 1.26681205e-01, 8.88981247e-01, 3.27597748e-01, 2.11918105e-01, - 4.53124549e-01, 4.53515422e-01, 5.26377028e-01, 7.95979022e-02, - 1.43994358e-01, 1.72639033e-01, 6.86574596e-01, 2.08833889e-01, - 4.64292165e-01, 2.28840915e-01, 6.44747821e-01, 2.83860723e-01, - 8.96164705e-01, 5.57991439e-01, 3.13723362e-01, 2.86391800e-01, - 5.97732000e-02, 5.77854059e-01, 1.46509010e-01, 6.17127238e-02, - 1.75310735e-01, 3.15108074e-01, 6.37357304e-01, 1.78678284e-01, - 9.68737195e-02, 1.36273898e-02, 3.48571761e-01, 3.86517950e-02, - 8.69163770e-01, 7.74626192e-01, 5.59529291e-01, 5.43916979e-01, - 2.06374565e-01, 5.61446719e-01, 2.28060102e-01, 2.72195059e-02, - 8.09775829e-01, 6.45183218e-02, 7.80265319e-01, 5.81126242e-01, - 1.05437216e-01, 9.82555548e-01, 3.40004880e-01, 7.55473931e-01, - 5.27551267e-01, 7.20772248e-01, 5.16017945e-01, 1.91320457e-01, - 3.99808545e-01, 5.33111934e-01, 4.88030268e-01, 4.31415070e-01, - 2.73758531e-01, 6.18416935e-01, 8.60684714e-01, 6.03515970e-01, - 5.06490523e-01, 9.68396224e-01, 5.94614961e-01, 2.54300061e-01, - 8.42904794e-01, 8.43923209e-01, 7.14167922e-01, 6.13974807e-01, - 5.92883321e-02, 6.90846061e-01, 9.49899961e-01, 6.17620472e-01, - 4.14537612e-01, 6.69297245e-01, 9.23615755e-01, 2.28977224e-01, - 8.41442344e-01, 6.38555273e-01, 5.05087021e-01, 7.45835163e-01, - 1.36977725e-01, 3.39499297e-01, 3.10317820e-01, 1.63572325e-01, - 6.69528006e-01, 2.35521917e-01, 2.81648723e-01, 9.00264371e-01, - 8.07149800e-01, 2.34513733e-01, 4.08127678e-01, 3.37133193e-01, - 6.79799048e-01, 4.17952092e-03, 7.21326725e-01, 5.23310620e-01, - 6.61873846e-01, 9.79183823e-01, 1.56469089e-01, 1.70150086e-01, - 4.11362464e-01, 6.65975294e-01, 9.97119465e-02, 2.07408602e-02, - 1.29615596e-01, 6.29580237e-01, 2.63098622e-03, 6.69340165e-01, - 2.62477123e-01, 5.03887900e-01, 8.15204402e-01, 4.34447491e-01, - 9.60351549e-01, 7.33327700e-01, 1.22530589e-01, 6.87243162e-01, - 8.62927819e-01, 6.12647119e-01, 5.37735304e-01, 7.08919259e-01, - 6.25161420e-02, 9.29647271e-01, 9.78718579e-02, 9.43608886e-01, - 6.77013798e-01, 2.57923383e-01, 2.18889887e-01, 5.41869014e-01, - 3.15095945e-01, 5.85548291e-01, 8.21181213e-02, 6.78003905e-01, - 8.35681922e-01, 2.65473381e-01, 4.07713329e-01, 5.20809763e-02, - 1.13691471e-01, 3.83928998e-01, 9.42417881e-01, 3.13015690e-01, - 7.32306724e-01, 6.97258862e-01, 2.40237433e-02, 7.55086547e-01, - 2.07239310e-01, 1.49344542e-01, 9.67428566e-01, 6.56127380e-01, - 2.82121060e-01, 6.06754076e-01, 9.87513254e-01, 1.01864388e-01, - 9.15830900e-01, 1.13851964e-01, 3.53913901e-01, 6.85123968e-01, - 1.29817387e-01, 3.43314773e-01, 8.32716787e-01, 3.99683297e-01, - 1.36911394e-01, 4.82708400e-01, 9.82539719e-01, 5.23252139e-01, - 6.56238621e-01, 7.25044407e-01, 2.27467943e-01, 2.66302669e-01, - 3.76417429e-01, 8.23316684e-01, 6.65196243e-01, 1.80598271e-01, - 9.91211952e-01, 6.70185150e-01, 9.90687722e-01, 4.15884057e-01, - 9.54460710e-02, 7.78124818e-01, 9.55094568e-01, 3.15561781e-01, - 5.17903148e-01, 4.90402405e-01, 7.03455959e-01, 9.48218682e-02, - 8.46576275e-01, 6.14295388e-01, 3.84444522e-01, 4.43093374e-01, - 8.24536392e-02, 1.62924744e-01, 8.82000785e-01, 7.52974207e-01, - 9.44832231e-01, 1.50927336e-01, 2.13498232e-01, 1.46902912e-01, - 9.17497331e-01, 9.01705963e-01, 5.21162809e-02, 2.89294598e-01, - 1.93457937e-01, 4.52495902e-01, 8.45227779e-01, 6.29748789e-02, - 8.79505835e-01, 1.73411851e-02, 8.60930653e-01, 4.39204654e-01, - 2.60893260e-01, 4.94379715e-01, 2.91115193e-01, 5.75444758e-01, - 2.38248819e-01, 9.92256274e-01, 4.90458918e-01, 1.61784888e-01, - 2.74124457e-01, 2.49226529e-01, 9.29961704e-01, 8.29609286e-01, - 1.11165349e-02, 3.72187970e-01, 3.16178599e-01, 7.91197905e-01, - 1.43127926e-01, 3.78670302e-01, 2.65774420e-01, 1.04441848e-01, - 3.86767239e-01, 8.55258488e-01, 1.64857941e-01, 5.97731844e-01, - 4.51109142e-01, 1.33584542e-01, 6.02753062e-02, 1.29791658e-01, - 1.92910470e-01, 9.64599025e-01, 3.13008773e-01, 3.83875683e-01, - 4.61411653e-01, 4.56330158e-01, 3.16344749e-01, 5.94772183e-01, - 9.98406983e-01, 9.72818293e-01, 7.15445049e-01, 4.37578976e-02, - 2.55096086e-01, 8.51788029e-01, 2.27137283e-01, 8.07410494e-01, - 4.11883527e-01, 8.09334564e-01, 2.91330410e-01, 3.06148260e-01, - 7.80591283e-01, 8.98608108e-01, 2.93627628e-01, 4.33710172e-01, - 5.00386377e-01, 2.83951401e-01, 1.12132167e-01, 9.81444938e-01, - 9.42865888e-01, 7.95462892e-01, 2.00289958e-01, 6.98474943e-01, - 4.84074712e-01, 5.02624245e-01, 1.70857752e-01, 8.34261880e-01, - 4.34606572e-01, 8.21110160e-01, 4.29546752e-01, 6.55869735e-01, - 6.72932563e-02, 5.11468224e-01, 1.83575478e-01, 7.82262752e-01, - 5.54239645e-01, 9.30544690e-01, 5.55978504e-01, 5.94879140e-01, - 3.57362300e-01, 5.51114228e-01, 5.11258693e-01, 5.52578515e-01, - 5.85758455e-01, 4.72205396e-01, 1.89726431e-02, 1.36742917e-01, - 9.77203154e-01, 6.97646853e-01, 9.18953944e-01, 8.26671595e-01, - 3.06945097e-01, 8.92446774e-01, 9.82894499e-01, 8.55807439e-01, - 8.56302056e-01, 7.96966594e-01, 1.33815409e-01, 2.74511784e-01, - 9.45375683e-01, 3.92379873e-01, 1.49454135e-01, 6.51447592e-01, - 3.15268758e-01, 1.11479884e-01, 5.45238749e-01, 1.09171159e-01, - 6.79982053e-01, 9.01266608e-01, 9.99758656e-01, 7.71427341e-01, - 6.34444975e-01, 9.53738456e-02, 5.98671577e-02, 5.83470928e-01, - 4.27922470e-01, 8.58167597e-01, 4.75199107e-01, 1.95104631e-01, - 4.45547585e-01, 1.17368608e-01, 2.47596320e-01, 3.32411043e-01, - 8.57845428e-01, 2.08684864e-01, 7.44072745e-01, 8.34623832e-01, - 4.90542906e-01, 1.83867392e-01, 7.94427073e-01, 6.15143040e-01, - 3.06336995e-01, 6.69799267e-01, 4.19959498e-01, 1.64766311e-01, - 5.27404557e-02, 7.08642104e-01, 1.63948085e-01, 2.87927400e-01, - 7.56459286e-02, 3.92093004e-01, 2.18885020e-01, 4.47518885e-01, - 2.30681052e-02, 5.71202115e-01, 6.08608749e-01, 6.81218143e-01, - 1.75838778e-01, 9.81844587e-01, 3.82605867e-02, 5.26032892e-01, - 5.35347799e-01, 8.24972356e-01, 9.24987993e-01, 3.07283826e-02, - 7.26027195e-01, 4.61810435e-01, 7.25649829e-01, 9.53607051e-01, - 7.65353213e-01, 2.02132537e-02, 6.36697339e-01, 9.13388214e-01, - 9.58224912e-01, 7.15569458e-01, 5.27245300e-01, 7.32816592e-01, - 2.85380475e-01, 3.20896367e-01, 4.47828992e-01, 9.71167817e-01, - 2.56221285e-01, 7.16975666e-01, 6.04449935e-01, 9.49917982e-01, - 6.51284733e-01, 3.65633706e-01, 6.00058987e-01, 9.49061185e-02, - 1.24693991e-01, 1.91570994e-01, 3.60763345e-01, 9.74462161e-01, - 7.77632954e-02, 1.80040975e-01, 6.67094322e-01, 3.52522452e-01, - 7.09100885e-01, 2.88093261e-01, 5.11804998e-01, 8.89625517e-01, - 9.17330680e-01, 7.12463672e-01, 5.50162389e-01, 4.31818119e-01, - 2.24056361e-01, 2.88119290e-01, 3.56105269e-01, 7.05986912e-02, - 2.14221670e-01, 9.70022830e-01, 5.90998284e-01, 2.27749650e-01, - 4.27751989e-01, 8.41296511e-01, 1.44257543e-01, 7.96291711e-01, - 9.63740721e-01, 8.87250707e-01, 6.64631881e-02, 4.28938879e-01, - 7.98835409e-01, 9.23364660e-01, 8.84014902e-01, 6.27148792e-01, - 3.43610001e-01, 1.18396505e-01, 6.98240204e-02, 5.87337658e-01, - 4.12723315e-01, 2.70502573e-01, 7.70901026e-01, 4.15244223e-01, - 3.96870687e-01, 4.46747497e-01, 9.67870645e-01, 6.98832930e-01, - 9.23793996e-02, 9.72109353e-01, 1.60403810e-01, 9.48216758e-01, - 1.36222898e-01, 2.31399441e-01, 6.67547576e-01, 9.83334994e-01, - 5.28334060e-01, 7.64248605e-01, 6.16859186e-01, 7.62079876e-01, - 8.11861122e-02, 3.02162742e-01, 1.15441729e-01, 1.66696316e-01, - 5.08037961e-01, 8.11615380e-01, 4.32724665e-01, 8.76707283e-01, - 3.93076726e-01, 2.51058283e-01, 6.26391713e-01, 9.31200262e-01, - 4.33537763e-01, 5.13680779e-01, 6.08768932e-01, 4.38561208e-02, - 9.17764550e-01, 1.72580098e-01, 6.13626661e-01, 2.94865212e-01, - 9.41809459e-01, 3.80269352e-01, 3.69523633e-01, 2.45993660e-01, - 6.17057731e-01, 2.65016444e-01, 1.97643035e-01, 4.26843955e-02, - 6.31242423e-01, 5.31985633e-01, 7.78806736e-01, 4.06015878e-01, - 9.18073158e-01, 8.44735412e-01, 3.08973440e-01, 4.67886558e-01, - 2.47220207e-01, 1.81057659e-01, 6.89187124e-01, 2.86850870e-01, - 9.04788747e-01, 5.58144105e-02, 4.94954015e-02, 6.19401576e-01, - 9.86786782e-01, 4.43670730e-01, 2.73559613e-01, 4.80374592e-01, - 3.83982467e-01, 8.38094240e-01, 8.52386159e-01, 9.08448741e-01, - 1.27964139e-01, 4.20049817e-01, 6.53669359e-01, 4.76127942e-01, - 5.39329600e-01, 5.72320540e-01, 6.18876778e-01, 9.35410209e-01, - 6.64482253e-01, 5.60225061e-01, 3.74196817e-01, 7.86324500e-01, - 5.00768226e-01, 1.09086678e-01, 8.66148403e-01, 8.81441455e-02, - 4.08932478e-01, 3.29114757e-01, 2.62452676e-01, 8.83542188e-01, - 1.98059204e-01, 6.62082794e-01, 7.54058132e-01, 5.35987562e-01, - 6.10916164e-01, 8.38673148e-01, 9.14514960e-01, 1.59470322e-01, - 7.88226385e-01, 4.49959111e-01, 9.43590263e-02, 8.09634505e-02, - 4.84204320e-01, 1.52631291e-01, 4.24233589e-03, 3.44016214e-01, - 7.10700686e-01, 2.94080244e-02, 2.59189410e-01, 6.65763214e-02, - 5.24802848e-01, 8.05264317e-01, 3.65926335e-01, 3.79386940e-01, - 4.88413725e-02, 2.61042215e-01, 2.47488687e-01, 7.54681056e-01, - 4.71464597e-01, 2.72550270e-01, 9.99652267e-01, 6.85080139e-01, - 3.90135401e-02, 5.65043251e-01, 7.00775614e-02, 7.68480725e-01, - 3.55075682e-01, 6.26231932e-01, 9.35077946e-01, 5.89336892e-01, - 4.81097543e-02, 8.85469637e-01, 2.78013135e-01, 1.45685239e-01, - 9.46063080e-01, 3.56543129e-01, 1.70488453e-01, 1.25744350e-02, - 6.56398149e-02, 3.35308341e-01, 2.63578976e-01, 3.96929542e-02, - 4.68983308e-01, 6.80831739e-01, 7.00756750e-01, 6.37779370e-01, - 4.63898984e-01, 4.22244940e-01, 8.91506008e-01, 7.32244107e-01, - 8.18720906e-02, 8.94706795e-02, 2.66925819e-03, 3.14684697e-02, - 6.20052880e-01, 2.62956329e-01, 4.59523890e-01, 4.29524686e-01, - 5.61467679e-01, 2.37448341e-02, 6.61865564e-01, 2.82557472e-01, - 8.31034031e-01, 6.04689355e-02, 6.89960493e-01, 3.82867236e-01, - 7.25300227e-01, 9.68309449e-01, 6.29340476e-02, 3.57591987e-02, - 9.62638970e-01, 4.95106211e-01, 5.50461455e-01, 3.68302784e-01, - 1.73265281e-01, 4.06005746e-01, 3.75885343e-01, 7.41839872e-01, - 9.79304285e-01, 2.12989371e-01, 3.28154585e-01, 8.00886449e-01, - 3.40491035e-01, 9.37968873e-01, 9.71693077e-01, 3.35094131e-01, - 8.25710953e-01, 8.16638487e-01, 9.23203954e-01, 4.83146249e-02, - 7.63632459e-01, 8.41022301e-01, 9.52121768e-01, 4.20628843e-01, - 7.52257938e-01, 9.62400956e-01, 9.60043951e-01, 3.48746358e-02, - 5.65216728e-01, 4.40061274e-01, 2.05740588e-01, 5.12052016e-01, - 5.34453003e-01, 6.21597163e-01, 6.67527506e-01, 7.70121176e-01, - 6.31012388e-03, 4.75724569e-01, 6.16579919e-01, 1.18153781e-01, - 2.86415676e-01, 4.66663860e-01, 3.81876837e-01, 6.18906168e-01, - 8.73824632e-01, 7.74091439e-01, 9.37880950e-01, 5.09677506e-01, - 7.36384564e-01, 4.18190695e-01, 6.08185066e-01, 8.14176705e-01, - 7.06449728e-01, 6.10095406e-02, 6.08450023e-02, 7.41851696e-02, - 1.28725190e-01, 3.61447933e-01, 5.33970011e-02, 7.94488210e-01, - 9.45183984e-01, 3.20925505e-01, 9.66811962e-01, 6.59801252e-01, - 4.07095049e-01, 1.44426741e-01, 7.74755565e-01, 8.80817116e-01, - 4.10544826e-01, 1.74843735e-01, 3.90229640e-01, 1.85545825e-01, - 4.01208103e-01, 4.57355296e-01, 6.07578701e-01, 6.47966355e-01, - 2.56743210e-01, 6.56804053e-01, 3.32227468e-01, 6.00229815e-01, - 3.47242708e-01, 9.02969445e-01, 3.15309500e-01, 4.55802472e-01, - 7.71695065e-01, 7.98341078e-01, 6.57411720e-01, 1.98758875e-01, - 8.87107134e-01, 8.38011573e-01, 2.78958751e-01, 3.37113898e-01, - 5.97295169e-01, 1.73445095e-01, 1.31042831e-01, 4.18948261e-01, - 4.42501422e-01, 1.62787243e-01, 4.01877271e-01, 9.87490788e-01, - 5.66572768e-01, 5.29382537e-01, 9.97068903e-01, 9.23510397e-01, - 7.65952077e-01, 6.22102808e-02, 1.94407457e-01, 1.88688184e-01, - 5.95841901e-01, 2.90353412e-01, 5.46889956e-01, 2.88063889e-01, - 9.05040559e-01, 7.06262460e-01, 6.45778791e-02, 5.82536706e-01, - 7.37502657e-02, 9.05911173e-01, 2.49948561e-01, 6.32176169e-01, - 3.17138726e-01, 1.74861836e-01, 6.94935150e-01, 9.63148501e-01, - 8.27974967e-01, 1.74496387e-01, 7.80570414e-01, 7.70277644e-01, - 8.21469460e-01, 5.53280119e-01, 4.74679375e-01, 5.63452819e-02, - 3.50204295e-01, 1.09935961e-01, 5.00335043e-01, 4.59518830e-01, - 4.82661944e-01, 7.79635233e-01, 9.11577645e-01, 8.37074271e-01, - 1.06218334e-01, 6.61894523e-01, 8.17504230e-01, 1.01257143e-01, - 1.60481357e-01, 1.02673584e-01, 9.02316584e-01, 6.44972928e-01, - 5.32904638e-02, 8.94438680e-02, 7.36407797e-01, 3.34645367e-01, - 8.20179901e-02, 6.61853604e-01, 2.95691518e-01, 8.58580608e-01, - 6.06943840e-01, 9.64224351e-01, 3.14044471e-01, 3.86852755e-01, - 4.18146382e-03, 2.87528245e-01, 5.15237478e-01, 6.91323944e-01, - 3.90392657e-01, 4.97436300e-02, 9.45388564e-01, 5.41323604e-01, - 9.76321456e-01, 3.61046072e-01, 5.97269496e-01, 5.87112685e-01, - 3.02623055e-01, 4.21488461e-01, 4.61471906e-01, 7.07562855e-01, - 9.76950026e-01, 4.08164489e-01, 1.17914934e-01, 1.59743284e-01, - 5.63966962e-01, 8.56956445e-01, 7.87062706e-01, 1.43730956e-01, - 5.45003941e-01, 2.04064374e-01, 1.16031920e-01, 3.47203102e-01, - 3.62803456e-01, 8.80334329e-01, 2.43595213e-01, 6.74743597e-01, - 1.18138396e-01, 9.50954586e-02, 4.08779476e-01, 8.96756252e-01, - 9.74174738e-01, 7.26373193e-01, 4.63050648e-02, 3.52940713e-01, - 9.38579368e-01, 2.38438009e-01, 9.25880655e-01, 7.98281828e-01, - 1.50950891e-01, 6.18452453e-01, 7.39062939e-01, 2.33972119e-01, - 2.25166326e-01, 1.34080629e-01, 9.15752293e-01, 4.30114261e-01, - 9.74359742e-01, 4.19977877e-01, 7.80747056e-01, 4.96372273e-01, - 2.64323180e-01, 9.77061896e-01, 3.47528219e-01, 9.97990581e-01, - 9.73876292e-02, 7.64051873e-01, 5.42059077e-01, 6.87290372e-03, - 7.03490416e-01, 5.00093339e-02, 2.07963007e-01, 7.01977608e-01, - 9.32281541e-01, 6.74998117e-01, 7.50587832e-02, 2.66057722e-01, - 4.21820451e-01, 3.44778833e-01, 7.47740264e-02, 1.36901833e-01, - 1.04557631e-01, 9.33866576e-01, 8.56143904e-01, 2.54388189e-01, - 4.83347831e-01, 6.10157306e-01, 6.53228002e-01, 5.79304368e-01, - 6.39274961e-02, 9.85907925e-01, 9.81760836e-01, 7.98927862e-01, - 2.21472711e-01, 4.30357966e-01, 1.82336985e-01, 7.18309623e-02, - 4.31570489e-01, 9.27112783e-01, 6.97018225e-02, 2.74141762e-01, - 1.64430290e-01, 2.72405990e-01, 9.39344694e-01, 7.26754788e-01, - 3.55943946e-01, 1.19201333e-01, 4.05683192e-01, 7.76101234e-01, - 5.59559636e-01, 5.69339612e-01, 2.75641508e-01, 6.34215452e-01, - 6.00382636e-01, 1.46210228e-01, 9.41941543e-01, 4.85583573e-01, - 3.74622491e-01, 7.44596714e-01, 6.54545216e-01, 4.20165196e-01, - 5.11594525e-01, 1.37475434e-01, 4.50806509e-01, 6.99882454e-01, - 9.95488724e-01, 6.39245429e-01, 7.50350490e-02, 3.12114831e-01, - 3.47595455e-01, 4.29320733e-01, 5.50589733e-01, 5.34776605e-01, - 4.56549603e-01, 6.31550990e-01, 9.60056330e-01, 9.05569337e-01, - 9.89919133e-01, 9.50830516e-01, 6.89600929e-01, 6.41082819e-01, - 8.07187388e-01, 3.62964645e-01, 3.92638872e-01, 9.13878850e-01, - 3.50776636e-01, 6.76043191e-01, 2.12791066e-01, 3.42245136e-01, - 7.67042252e-01, 3.88472593e-01, 1.63296357e-01, 7.64053078e-01, - 1.75466677e-01, 3.76815779e-01, 9.65846358e-01, 9.55781684e-01, - 4.52065609e-01, 9.55350089e-01, 1.90581373e-01, 7.46196607e-02, - 9.63626146e-01, 3.17247835e-02, 9.07884411e-01, 5.00037485e-01, - 3.03986070e-01, 3.63880030e-01, 9.19447621e-01, 4.00030889e-01, - 8.34088054e-01, 6.13295406e-01, 6.46826177e-01, 3.18945584e-01, - 1.60945497e-01, 3.45782958e-01, 6.92872779e-02, 6.81971054e-01, - 8.19983072e-01, 7.39375905e-01, 4.16506388e-02, 1.18896078e-01, - 3.48979571e-01, 7.73400491e-01, 8.25352926e-01, 1.89126791e-01, - 8.05253340e-01, 6.27346424e-01, 1.91032452e-01, 4.56431152e-01, - 7.07081172e-01, 3.34673953e-01, 2.18900686e-01, 5.06215808e-02, - 4.77174556e-01, 4.36146106e-01, 8.20932455e-01, 5.96163888e-01, - 5.31083479e-01, 9.21358950e-01, 2.93185215e-01, 9.58205287e-01, - 3.20887685e-01, 8.69121760e-01, 7.94031243e-02, 2.07362894e-02, - 6.88503971e-01, 1.73461388e-01, 4.09625305e-02, 1.30144930e-01, - 5.73262464e-01, 9.94783540e-01, 3.41687060e-01, 8.90181528e-01, - 4.32269634e-01, 3.17332715e-01, 9.09746235e-01, 8.94719298e-01, - 9.30473163e-01, 5.37484415e-01, 6.20943067e-01, 3.98758707e-01, - 3.35593149e-02, 1.20211283e-01, 5.90303647e-01, 6.55558929e-02, - 1.11802061e-01, 5.82635576e-01, 5.11702210e-01, 3.12911085e-01, - 7.74801586e-01, 9.49704238e-01, 1.00576454e-01, 1.66847008e-01, - 3.98241342e-01, 6.71887110e-01, 8.54376842e-01, 8.62468560e-01, - 3.04115488e-01, 6.87066152e-01, 7.10335863e-01, 2.37908990e-01, - 7.88544539e-01, 8.07316022e-01, 4.47620475e-01, 9.12845203e-01, - 2.95443529e-01, 1.03519141e-01, 3.46729040e-01, 7.03346617e-01, - 4.83586791e-01, 2.86845230e-01, 4.04984531e-01, 1.87200554e-01, - 3.01758021e-01, 8.41834523e-01, 6.03005083e-01, 3.85012355e-01, - 6.71631379e-01, 3.84784509e-02, 2.83588981e-01, 5.69737771e-01, - 4.54740703e-01, 9.28387202e-01, 4.38227539e-01, 6.71129161e-01, - 2.48419057e-01, 9.86495977e-01, 3.22837329e-01, 7.24915921e-01, - 8.43628445e-01, 6.63838724e-01, 2.56677813e-01, 2.20931776e-01, - 4.41666478e-01, 5.27767851e-02, 2.68927431e-02, 3.49834264e-01, - 5.11565536e-01, 8.80963125e-01, 4.38673079e-01, 8.93248328e-01, - 4.58276188e-01, 1.77053103e-01, 3.71858384e-01, 9.99780376e-01, - 7.80501873e-01, 2.65394139e-01, 2.25218860e-01, 4.42027258e-01, - 3.00543910e-01, 2.79238734e-01, 3.58628815e-01, 8.35333999e-01, - 7.16029244e-02, 3.76915423e-02, 1.80127988e-01, 1.62889643e-02, - 6.02145700e-01, 5.01767023e-01, 8.02582834e-01, 7.44893117e-01, - 2.39221273e-01, 9.92019200e-01, 1.34508613e-01, 3.37111091e-01, - 9.16794821e-01, 3.30985085e-01, 5.58162751e-01, 2.62423639e-01, - 9.82453849e-01, 9.01893007e-01, 5.48791870e-01, 5.72496673e-01, - 9.88055944e-01, 4.16654333e-01, 5.86550574e-01, 1.90380230e-02, - 4.84423367e-01, 3.71512376e-01, 6.81597973e-01, 6.98827854e-01, - 6.87943499e-01, 7.46831351e-01, 1.31785127e-02, 3.40233093e-01, - 1.40710944e-01, 8.64518863e-01, 5.64835915e-01, 7.45310700e-01, - 1.52336418e-01, 9.08736423e-03, 4.59945139e-01, 9.42465539e-02, - 1.12567403e-01, 1.98660782e-01, 6.01430746e-01, 9.06232333e-01, - 4.28312092e-01, 5.27729205e-01, 8.84416814e-03, 2.39647940e-01, - 4.91474715e-01, 6.95213144e-01, 3.77249302e-01, 8.79430787e-01, - 6.34006134e-01, 7.19389691e-01, 8.51835635e-01, 7.78467626e-01, - 1.74993909e-01, 7.90886223e-01, 3.28002963e-02, 5.10988615e-01, - 5.02353376e-01, 7.14365230e-01, 3.53268896e-01, 5.50970666e-01, - 5.81049677e-01, 6.71265418e-01, 1.77240858e-03, 8.68355224e-01, - 1.75909166e-01, 9.58530790e-01, 1.47608939e-01, 7.35674896e-01, - 3.32165079e-01, 2.95203021e-01, 4.06235236e-03, 5.30335365e-01, - 4.68319802e-01, 1.83639665e-01, 3.05326650e-01, 8.16752763e-01, - 4.37674064e-01, 2.42786905e-01, 1.93591813e-01, 1.93503206e-01, - 1.63315947e-01, 8.20632916e-01, 4.02131155e-02, 2.77254521e-01, - 2.29075315e-01, 1.09260118e-01, 3.52436874e-01, 8.55930413e-01, - 2.26078646e-01, 5.00127022e-01, 3.20940961e-01, 5.01200557e-01, - 9.09853426e-01, 7.81909710e-01, 7.89344644e-01, 2.11555966e-01, - 3.05351180e-01, 2.68138024e-01, 7.98352470e-01, 8.58311690e-01, - 1.80452631e-01, 3.19224183e-01, 6.55469263e-01, 7.96099079e-01, - 2.32678360e-01, 8.94487688e-01, 6.47173538e-01, 3.67753864e-01, - 1.40405581e-01, 4.37813857e-01, 3.19217073e-01, 1.38785589e-01, - 8.08768036e-01, 7.96708070e-01, 4.07268132e-01, 1.37554966e-01, - 1.85723372e-01, 1.00201311e-01, 3.87051523e-01, 3.61065129e-01, - 1.71838044e-01, 4.89252468e-01, 5.96842515e-01, 2.71747006e-01, - 1.09541712e-01, 3.48533605e-01, 1.42106437e-01, 4.19123313e-01, - 2.87764859e-02, 6.63468055e-01, 9.91460691e-01, 1.49475978e-01, - 8.31455868e-01, 8.62946210e-02, 1.78712503e-01, 4.45288590e-01, - 2.05984316e-01, 5.05270844e-01, 4.17400416e-02, 2.10584390e-01, - 8.52235054e-02, 3.79741630e-01, 3.47130720e-01, 1.89172952e-01, - 8.29253193e-01, 9.83182113e-01, 6.56200204e-01, 2.40791697e-01, - 8.66918485e-02, 6.62608354e-01, 3.42895904e-01, 3.13135770e-01, - 4.89450311e-01, 9.81945246e-01, 2.24373613e-01, 1.95066894e-01, - 5.31521914e-01, 2.38755730e-01, 8.73314648e-01, 7.38295608e-01, - 1.97668409e-01, 6.29815923e-01, 7.48782414e-01, 4.63727717e-01, - 4.08905145e-01, 1.52806182e-01, 8.64708262e-01, 7.32649119e-01, - 4.92471818e-01, 1.58355632e-01, 4.10387107e-01, 6.74947769e-01, - 6.51081826e-01, 4.40716769e-01, 1.03992746e-01, 7.91779747e-01, - 5.89023279e-01, 1.95508533e-03, 9.58791604e-01, 7.14453423e-02, - 2.65693113e-01, 3.40551770e-01, 2.05525586e-01, 8.88155039e-01, - 4.71269973e-01, 2.69948067e-01, 5.27269508e-01, 5.01994326e-01, - 5.23530428e-01, 9.16343977e-02, 4.82916813e-01, 4.17407263e-01, - 2.30483113e-01, 6.18783139e-01, 3.54866004e-01, 4.32938429e-01, - 5.55163693e-02, 3.18713205e-01, 4.75861140e-01, 9.39934808e-01, - 3.32654562e-04, 9.25126170e-01, 9.17292724e-02, 7.87674904e-01, - 6.45444189e-01, 9.45603844e-01, 7.20766270e-01, 2.49602245e-01, - 2.42740307e-01, 9.45684078e-02, 2.52042007e-01, 4.96740732e-01, - 3.90514803e-01, 7.04841888e-01, 2.28977827e-01, 7.58324849e-01, - 9.56302951e-01, 9.92172185e-01, 3.35505496e-01, 7.31062910e-01, - 2.65275508e-01, 4.85947503e-01, 2.39967130e-01, 6.55884020e-01, - 8.81661084e-01, 9.44992478e-01, 8.15575232e-01, 8.20967518e-01, - 3.63462321e-01, 2.70739059e-01, 7.34649284e-01, 7.84702472e-01, - 5.86517029e-01, 3.48718909e-02, 8.08280907e-01, 7.98705019e-02, - 8.52340877e-01, 1.12333976e-01, 8.69629076e-01, 7.12914602e-01, - 8.77362692e-01, 6.57353647e-01, 2.45196648e-01, 6.81771700e-01, - 4.28040262e-01, 7.24897734e-01, 5.13875315e-01, 5.55731348e-01, - 2.32093533e-01, 3.66129782e-01, 2.46871359e-01, 4.13743295e-01, - 6.81699554e-01, 5.31208366e-01, 4.70497296e-01, 4.12937903e-01, - 3.82364880e-01, 4.67399014e-01, 2.56072172e-01, 8.29287260e-01, - 7.45233038e-01, 5.59245496e-01, 4.60209562e-01, 5.27085126e-01, - 1.79489811e-01, 2.78117901e-01, 3.70673679e-02, 8.10906362e-01, - 4.24150657e-02, 7.21429857e-01, 3.15197341e-01, 6.13853198e-02, - 7.64076244e-01, 4.43850995e-02, 3.42261056e-02, 2.05102034e-01, - 3.29423518e-01, 3.44886444e-01, 6.96171546e-01, 7.67902815e-01, - 2.82685517e-01, 8.87451937e-01, 2.00156099e-01, 4.58022319e-01, - 9.92738656e-01, 1.42457317e-01, 5.24176119e-01, 6.45880600e-01, - 7.02636082e-01, 4.09585698e-01, 4.71450907e-02, 1.61357063e-01, - 1.87931919e-01, 6.17340633e-01, 1.21272058e-01, 8.70088711e-01, - 3.67712200e-02, 7.87877050e-01, 8.09877675e-01, 7.28020115e-01, - 2.58105115e-01, 2.96696599e-01, 1.74100663e-02, 9.13461897e-01, - 9.13327484e-01, 5.31520357e-01, 7.55329909e-01, 1.36846592e-01, - 6.29202192e-01, 6.23276699e-02, 6.20152988e-01, 5.41082187e-01, - 3.80813779e-01, 4.01999700e-01, 6.50019595e-01, 5.39472632e-01, - 8.69135498e-01, 8.22734833e-01, 1.66716737e-01, 7.88198946e-01, - 4.13234600e-01, 9.09346233e-01, 7.54557649e-01, 7.41814281e-01, - 5.70210395e-01, 8.54038442e-01, 3.83804711e-02, 5.22029323e-01, - 9.33984149e-01, 9.40383170e-02, 5.61376332e-01, 7.00904489e-01, - 4.56901588e-01, 1.19418932e-01, 2.12451795e-01, 1.47509627e-01, - 3.86119692e-01, 8.34627498e-01, 4.19214401e-01, 4.09600370e-01, - 4.63936888e-01, 8.68129290e-02, 4.51024183e-01, 7.85286896e-01, - 9.55640011e-01, 6.29081179e-01, 9.01006547e-01, 8.47311890e-01, - 1.93194272e-01, 6.99090093e-01, 3.94260918e-01, 9.09225996e-01, - 7.30348061e-01, 3.60759292e-01, 7.04730102e-01, 7.89231408e-01, - 7.65067412e-01, 5.55551444e-01, 4.74987804e-01, 5.15585983e-01, - 4.99860306e-01, 6.23858200e-01, 9.88767757e-01, 7.59155571e-01, - 7.81156552e-01, 7.09345902e-02, 8.18154306e-01, 4.36901386e-01, - 6.36775360e-01, 7.64778994e-01, 9.13415902e-01, 3.84131791e-01, - 4.05706919e-01, 5.06080682e-01, 1.40408408e-01, 6.08390498e-01, - 7.75143381e-02, 6.09403869e-01, 3.22736094e-02, 9.25164512e-01, - 9.62963785e-01, 5.47097112e-01, 9.75645860e-01, 4.26292446e-01, - 8.37163224e-01, 9.29986616e-01, 3.33631403e-01, 1.24604936e-01, - 8.44057799e-01, 7.65297525e-01, 5.97567375e-01, 3.64837836e-01, - 6.97693392e-01, 1.90614794e-01, 1.14320442e-01, 7.64117228e-01, - 1.57938635e-01, 8.64849288e-02, 8.38951546e-01, 1.16393362e-01, - 3.60523994e-02, 5.18621460e-01, 9.34860501e-01, 5.52268492e-01, - 4.13962508e-01, 8.93529638e-01, 3.53612069e-01, 5.57069292e-01, - 7.11374848e-01, 6.21821983e-01, 3.49795226e-01, 6.22511243e-01, - 8.47361946e-01, 3.06124725e-01, 2.96303659e-01, 5.93372330e-01, - 6.14929754e-02, 2.93878476e-01, 3.89298168e-01, 2.68298736e-01, - 8.70898180e-01, 3.77342326e-01, 9.76330231e-01, 3.40606899e-01, - 9.93538450e-01, 7.69074825e-01, 3.82799165e-01, 8.59370261e-01, - 8.81389769e-01, 2.78814769e-01, 3.75621865e-01, 2.77644505e-01, - 8.92055026e-01, 7.44626111e-01, 3.21168748e-01, 4.60433843e-01, - 1.00546338e-01, 5.62289832e-01, 5.08464387e-01, 6.56255345e-01, - 9.47911969e-01, 6.90855939e-01, 4.78644948e-01, 1.34185684e-01, - 4.30400642e-01, 8.41191330e-01, 4.65513954e-01, 3.50046231e-01, - 2.66173515e-01, 3.56863844e-01, 6.73404912e-01, 3.24343279e-01, - 1.35571167e-01, 7.91268387e-01, 3.39882763e-02, 8.24100191e-02, - 9.44319164e-01, 2.38671559e-01, 2.52321380e-01, 2.81938456e-01, - 6.02851042e-01, 8.68074849e-01, 1.79939176e-01, 5.87776452e-01, - 2.79526963e-01, 8.10512342e-01, 2.30689512e-01, 1.29700840e-01, - 7.16583612e-01, 8.50513097e-01, 9.22311895e-01, 6.57592273e-01, - 9.28874172e-01, 7.43244822e-01, 9.68863925e-02, 6.36000009e-01, - 5.06236072e-01, 9.98243861e-02, 2.04019993e-01, 7.97635869e-01, - 2.74243985e-02, 8.40244762e-01, 3.26961810e-01, 5.77010022e-01, - 3.11169408e-01, 4.10332088e-01, 8.77483092e-01, 2.93716266e-01, - 8.22536238e-01, 3.99455126e-02, 6.70739251e-01, 9.45414350e-01, - 2.24131761e-01, 6.58385601e-01, 3.14792216e-01, 1.42281886e-01, - 9.36157697e-01, 3.73417620e-01, 9.89129857e-01, 5.82213166e-01, - 6.11650836e-01, 9.66779532e-01, 3.87011737e-01, 4.08860754e-01, - 7.94275517e-01, 4.94225320e-01, 7.49977255e-02, 5.97561663e-01, - 9.73264753e-01, 3.43786385e-01, 8.19731176e-01, 1.79011756e-02, - 3.35124754e-01, 4.33870639e-01, 8.49037855e-01, 3.03619782e-01, - 3.30553265e-02, 7.98049298e-01, 7.52795367e-01, 3.16463587e-01, - 2.65180850e-01, 1.12909106e-01, 4.54742492e-01, 9.60433138e-01, - 7.43190883e-01, 9.25185733e-01, 3.55492469e-01, 8.31973385e-01, - 1.93456874e-01, 8.55537061e-01, 7.08145720e-01, 2.65625356e-01, - 5.15945695e-01, 4.98082091e-01, 4.88479507e-01, 6.88269121e-01, - 3.83142787e-01, 4.34293708e-01, 6.65411085e-01, 5.29845249e-01, - 6.10655112e-01, 2.90666547e-01, 5.39064518e-01, 4.18583745e-01, - 9.51910484e-01, 4.67264825e-01, 8.63619911e-01, 1.43812416e-01, - 3.65441883e-01, 1.51903355e-02, 2.91651822e-01, 1.46398723e-01, - 4.26408061e-01, 6.52947680e-01, 5.78798086e-01, 5.62569135e-01, - 5.61162974e-01, 7.01687660e-01, 1.16848091e-01, 2.81601787e-01, - 1.90239966e-02, 7.85435004e-01, 3.69065150e-01, 3.51738794e-01, - 3.92916412e-01, 5.13621859e-01, 3.23188309e-01, 6.03319428e-01, - 3.45303179e-01, 3.08774018e-03, 5.39986636e-01, 8.47477186e-01, - 9.65414852e-01, 1.79164825e-01, 4.44995403e-01, 2.46904669e-01, - 5.13122272e-01, 4.90742951e-01, 1.15099119e-01, 2.87047326e-01, - 4.69629412e-01, 2.97830893e-01, 8.49407377e-01, 6.60486857e-01, - 3.64270079e-02, 5.22093120e-01, 5.22731141e-01, 2.40812380e-01, - 7.22398685e-01, 4.19020099e-01, 8.08851109e-01, 2.25022070e-01, - 5.54232845e-01, 7.53350331e-01, 7.47244253e-01, 9.00042018e-01, - 9.15222228e-01, 4.44562479e-01, 9.64952490e-01, 5.05577907e-01, - 6.86374211e-01, 6.60364564e-01, 8.86718906e-01, 6.46747284e-01, - 4.47963222e-01, 3.84895099e-01, 7.50738725e-01, 3.71259709e-02, - 3.45042053e-01, 9.33599800e-01, 8.06397726e-01, 2.09202761e-02, - 7.93360593e-01, 1.64686557e-01, 7.52163417e-01, 7.27035203e-01, - 1.95849437e-01, 9.33039885e-01, 5.57272389e-01, 9.91927926e-01, - 7.84055433e-01, 1.11178323e-01, 9.49985534e-01, 5.10225195e-01, - 6.85958972e-02, 6.15635484e-01, 4.57068119e-01, 7.26102504e-02, - 7.53839197e-01, 5.30583339e-01, 8.82248410e-01, 6.43368275e-01, - 5.51899777e-01, 1.10580029e-01, 1.74628930e-01, 7.06735629e-01, - 1.26095785e-01, 5.89298206e-01, 2.63810321e-01, 5.67592501e-01, - 9.82917535e-01, 9.54790963e-01, 6.11809713e-01, 6.91264866e-01, - 4.50402116e-01, 4.99215210e-01, 2.46185061e-01, 7.21885224e-01, - 8.59774301e-01, 6.32945619e-01, 5.54326262e-01, 3.29084388e-01, - 3.05617409e-01, 9.51080886e-01, 4.48145812e-01, 3.01954074e-01, - 2.38565150e-01, 1.16778491e-01, 6.11846618e-01, 3.11523695e-01, - 5.71679522e-01, 8.92536352e-02, 2.75055495e-01, 7.01036815e-01, - 9.59680220e-02, 8.95142111e-01, 1.49563921e-01, 7.21352887e-02, - 5.86497519e-01, 5.21234097e-01, 4.94624985e-01, 3.71474724e-01, - 5.91348911e-01, 6.07333893e-01, 6.90816381e-02, 8.18729415e-01, - 8.26887268e-01, 5.62247191e-01, 4.94071282e-01, 3.94966549e-01, - 4.10248006e-02, 9.91473084e-01, 6.48210683e-01, 2.29029461e-02, - 4.62800527e-01, 4.39322054e-01, 6.76484522e-02, 7.54381617e-01, - 3.77258368e-01, 8.22950883e-02, 4.63559653e-02, 5.14305768e-01, - 1.66000403e-01, 1.78812598e-01, 4.52404254e-01, 8.69937019e-01, - 9.41252026e-01, 8.66955146e-01, 8.43281460e-01, 5.80263735e-01, - 3.41063752e-01, 4.03031265e-01, 5.65100019e-01, 9.77042443e-01, - 9.60312975e-01, 5.74597787e-01, 3.22997391e-01, 3.24983262e-03, - 4.43717746e-01, 4.84440157e-02, 4.99642598e-01, 9.86758454e-01, - 2.39430788e-01, 2.72954938e-01, 6.89101173e-01, 1.05343160e-01, - 1.51451333e-01, 8.17604560e-01, 4.67208215e-01, 3.91459202e-01, - 2.95019639e-01, 2.12308619e-01, 9.77405041e-01, 4.45883911e-01, - 2.61725427e-01, 5.81538691e-01, 5.32163676e-01, 3.41124703e-01, - 4.22540898e-02, 3.34673505e-01, 5.30623929e-01, 1.71977789e-01, - 2.02391824e-01, 4.66763022e-01, 1.69646300e-01, 5.71158219e-01, - 2.81367419e-01, 3.00175865e-02, 2.64695268e-01, 1.74878228e-01, - 9.76519310e-01, 4.47659478e-01, 9.20272934e-01, 5.96409555e-01, - 8.05608036e-01, 3.57010393e-02, 3.46509876e-01, 7.09918963e-02, - 6.90741825e-01, 5.19830901e-01, 4.95382668e-01, 9.61290616e-01, - 5.84269319e-01, 4.17797161e-01, 4.99306400e-01, 5.27035244e-01, - 6.80189764e-01, 8.27000537e-01, 1.65090264e-01, 5.22092046e-01, - 9.20523407e-01, 1.26916933e-01, 3.85893941e-01, 6.35174634e-01, - 9.57707038e-01, 5.28992563e-01, 1.54301499e-02, 4.75420611e-01, - 7.15566162e-01, 5.27958597e-01, 5.55606993e-01, 9.60247033e-01, - 8.22291586e-01, 7.51029219e-01, 1.45883022e-01, 8.38413405e-01, - 8.65781042e-01, 8.24377868e-01, 7.81568539e-02, 1.26891712e-01, - 1.38031346e-03, 7.75500335e-01, 9.48710588e-01, 3.81408722e-01, - 1.64746349e-01, 8.88377109e-01, 8.11157608e-01, 3.39860001e-01, - 4.98714142e-01, 6.79524511e-01, 6.90549636e-01, 4.19235861e-01, - 1.31426596e-01, 9.90129353e-01, 1.84148211e-01, 8.84928443e-01, - 7.12377418e-01, 9.76875556e-01, 8.98814150e-02, 7.68618335e-01, - 8.45561565e-02, 3.09705936e-01, 6.54816947e-01, 4.53957285e-01, - 4.68819247e-01, 6.40443434e-01, 4.82574320e-01, 1.61372660e-01, - 3.95605753e-01, 8.69935741e-01, 2.62842218e-01, 2.47460397e-01, - 8.26392986e-01, 8.57707953e-01, 5.76341020e-01, 2.41623804e-01, - 5.91300628e-01, 9.52778904e-01, 5.14037592e-01, 9.17708707e-01, - 9.23785575e-03, 3.28763403e-01, 1.57797246e-01, 7.18657229e-01, - 3.60501782e-01, 9.30129805e-02, 4.75363634e-01, 3.04279184e-01, - 8.45091284e-01, 3.01276430e-01, 3.40465321e-01, 4.28886187e-01, - 9.78781396e-01, 8.54169086e-01, 6.38341944e-01, 4.64619203e-01, - 2.65765952e-01, 5.06275206e-01, 5.63721268e-01, 4.51954452e-01, - 4.92542437e-01, 9.11940222e-01, 8.38359977e-01, 9.29150234e-01, - 1.60692151e-01, 3.08964271e-02, 3.20939183e-01, 3.41793713e-01, - 5.80537490e-01, 3.23643526e-02, 8.97891963e-01, 3.81963795e-01, - 4.51738899e-01, 2.33627450e-01, 6.57701880e-02, 3.30771434e-03, - 5.35730019e-01, 2.23364027e-01, 1.57358442e-01, 6.35025306e-01, - 9.25867681e-01, 8.56266730e-01, 3.52743283e-01, 6.68675591e-01, - 8.09976694e-01, 6.13852521e-01, 6.97601550e-01, 8.80538459e-01, - 2.54339833e-01, 3.33018975e-01, 6.93243317e-01, 9.10659280e-01, - 1.42074388e-01, 7.51608793e-01, 6.99298513e-01, 2.58288129e-01, - 3.49495315e-01, 2.33849789e-01, 8.46564392e-01, 8.90943715e-01, - 9.33784580e-03, 6.52728571e-01, 9.57766470e-01, 9.99605088e-01, - 3.41270690e-01, 3.55749108e-01, 4.82152563e-01, 2.60748018e-01, - 3.42590207e-01, 6.20017115e-01, 9.34608756e-01, 3.06143816e-01, - 1.09871103e-01, 5.36889458e-01, 3.85075507e-01, 7.53351188e-02, - 4.14997198e-01, 6.75721252e-01, 1.73986032e-01, 7.71189221e-01, - 6.08687182e-01, 2.82456664e-01, 8.21634073e-01, 1.98445823e-01, - 7.06222028e-01, 7.18953881e-01, 1.45163974e-01, 2.27375731e-01, - 7.33401928e-01, 1.39474016e-01, 7.82123589e-01, 9.23668890e-01, - 7.36285897e-01, 6.07458628e-01, 5.53468166e-01, 1.85407203e-01, - 3.75851635e-01, 5.10271141e-01, 3.77489223e-01, 1.55826108e-01, - 8.89950821e-01, 3.95779383e-01, 4.57472320e-01, 3.72631196e-01, - 6.81495766e-01, 2.78016971e-01, 6.14441701e-01, 7.73257484e-01, - 2.10025067e-01, 6.06231429e-01, 2.99844256e-01, 4.53852635e-01, - 7.06533872e-01, 3.82879823e-01, 8.42117999e-01, 4.65437165e-01, - 1.76544219e-01, 5.23976674e-01, 4.52350121e-01, 1.92663687e-01, - 9.99791424e-01, 8.67203847e-01, 5.35944920e-01, 6.66215768e-01, - 3.11246435e-02, 7.14665289e-03, 7.17017593e-01, 7.61070647e-01, - 9.12223959e-02, 6.73599046e-01, 1.91914212e-01, 5.58608202e-01, - 3.06762453e-01, 1.55931034e-01, 4.81379786e-01, 1.05595014e-01, - 4.22827762e-01, 3.83889484e-01, 7.43034367e-01, 2.24671939e-01, - 3.68336104e-01, 9.16762664e-01, 3.67618388e-01, 8.09515385e-01, - 3.73714961e-02, 9.37971395e-02, 8.42187625e-01, 9.05109486e-01, - 6.60976043e-01, 3.10705842e-01, 9.93173393e-01, 3.01811127e-01, - 9.11479358e-01, 1.59420075e-02, 1.11314334e-02, 1.54423243e-01, - 7.07319219e-01, 1.04201914e-01, 1.67164800e-01, 3.84742863e-01, - 8.29670813e-01, 5.64450467e-01, 4.93541123e-01, 2.25852196e-01, - 2.79268903e-01, 4.68336333e-01, 7.67643027e-01, 3.26045618e-01, - 1.66074747e-01, 5.42368455e-01, 8.67129004e-01, 9.72701399e-01, - 4.61517776e-01, 2.07237922e-01, 9.62676273e-02, 3.29877702e-03, - 5.78787337e-01, 8.55082652e-01, 1.08945833e-01, 3.98497903e-01, - 3.48467374e-01, 7.66397761e-01, 2.30019198e-01, 4.46880840e-01, - 1.90051974e-01, 9.08894121e-01, 4.95022535e-01, 4.01705728e-01, - 3.20636743e-01, 5.45621811e-01, 3.71018447e-01, 7.69313410e-01, - 8.28828483e-01, 6.44787491e-01, 2.12075802e-01, 6.31437100e-01, - 1.24206253e-01, 4.73453290e-01, 3.63277586e-01, 5.01884188e-01, - 1.71657839e-01, 6.02734530e-01, 6.05350365e-02, 9.55851544e-01, - 3.04549527e-01, 8.41278743e-01, 7.41457774e-01, 3.06333738e-01, - 9.11953951e-01, 4.63394077e-01, 4.81171199e-01, 1.70314561e-01, - 4.35150316e-01, 4.86410721e-01, 8.07722744e-01, 3.68034827e-01, - 9.62094967e-01, 9.45490907e-01, 1.10607837e-01, 4.26591720e-01, - 6.22372888e-01, 8.83572543e-01, 8.46188854e-02, 1.69052711e-01, - 7.06886120e-01, 8.82981456e-01, 5.29281587e-01, 5.74586877e-02, - 4.29081546e-01, 4.14354395e-01, 3.65314255e-01, 7.83532800e-01, - 3.32110020e-01, 6.08405408e-01, 5.64444447e-01, 2.16211706e-01, - 3.21855456e-01, 2.41180251e-01, 4.55148147e-01, 2.12509192e-01, - 1.12307729e-01, 6.74607466e-01, 1.27040975e-01, 1.39491284e-01, - 8.22288489e-01, 5.68113234e-01, 5.74764335e-01, 4.76652415e-01, - 1.11665389e-01, 1.11783738e-01, 2.13890517e-01, 7.89757414e-01, - 7.81403625e-02, 2.68297404e-02, 2.65885716e-01, 7.46387206e-01, - 7.39411871e-01, 5.25267870e-01, 9.42619230e-01, 3.97874483e-01, - 7.18339912e-02, 8.23615397e-01, 4.08398782e-01, 3.43668757e-01, - 6.03074731e-01, 5.10383918e-01, 6.27840954e-01, 6.97145252e-02, - 9.00888877e-01, 1.26661522e-01, 2.95337277e-01, 5.79932981e-01, - 7.33427963e-01, 9.61112463e-01, 9.26330785e-01, 2.10094601e-01, - 2.58272584e-01, 1.55687519e-01, 1.09180007e-01, 7.28044570e-01, - 8.60183244e-01, 1.60864698e-01, 5.12122727e-01, 8.13197067e-01, - 3.27217443e-01, 7.05708258e-01, 5.72727972e-01, 5.48144922e-01, - 2.99803195e-01, 9.72500701e-01, 2.39011325e-01, 4.52917253e-01, - 7.80297653e-01, 4.38528229e-01, 5.42639679e-01, 5.47325062e-01, - 2.42309305e-01, 4.05688817e-01, 4.64691344e-01, 2.81563660e-01, - 9.43489399e-01, 4.40455281e-01, 9.25558601e-01, 8.30389488e-02, - 4.89887798e-01, 9.92106025e-01, 7.68970476e-01, 9.76514587e-01, - 2.61805215e-01, 4.11684641e-01, 5.40791370e-01, 8.40783825e-01, - 4.21549776e-01, 7.83450488e-01, 7.30292683e-01, 9.23913080e-01, - 4.67319969e-01, 3.13629695e-01, 3.28363476e-01, 8.11060578e-02, - 6.87123996e-01, 6.92536699e-01, 4.46294870e-01, 1.83603865e-01, - 4.71452870e-01, 6.86586110e-01, 1.42083389e-01, 4.17469287e-01, - 6.98730811e-01, 2.71533805e-02, 5.82939883e-02, 5.63764113e-01, - 7.24985811e-01, 1.83851662e-01, 7.38398679e-01, 2.77057629e-01, - 8.67415559e-01, 1.58987095e-01, 5.13459878e-01, 7.58446477e-01, - 7.45788160e-01, 5.66934387e-01, 9.38167265e-01, 2.82546046e-01, - 3.96147569e-01, 5.02663180e-01, 2.31342197e-01, 6.30795831e-01, - 1.89199376e-01, 2.96681036e-01, 6.26581606e-01, 1.91753154e-01, - 8.59379810e-01, 9.33910631e-01, 9.70077992e-01, 8.83391078e-01, - 5.74543989e-01, 7.04284185e-02, 2.40850647e-01, 1.65883512e-02, - 4.27448258e-01, 9.02076193e-01, 4.43181022e-01, 9.30162550e-01, - 3.57301521e-01, 6.55273491e-01, 9.18686998e-01, 8.33580458e-03, - 5.62394931e-01, 2.94211261e-01, 5.61407997e-01, 4.05998299e-01, - 1.37611464e-01, 8.33751326e-01, 6.73421474e-01, 2.23195257e-01, - 6.60437659e-01, 9.00612394e-01, 2.94803355e-01, 4.20194653e-01, - 2.44480138e-01, 5.35331529e-01, 3.82888594e-01, 2.22416883e-01, - 1.65714859e-02, 4.78892134e-02, 3.24885698e-01, 8.71487752e-01, - 2.08378965e-01, 8.12842007e-02, 7.14228356e-01, 2.62316935e-01, - 4.56956809e-01, 3.68001130e-01, 4.07526017e-01, 7.32032001e-01, - 7.43484586e-01, 3.48233201e-01, 3.81066270e-01, 4.86081359e-01, - 4.66253714e-01, 9.74099640e-01, 3.75932451e-01, 7.94005853e-01, - 8.20943824e-01, 5.23543229e-01, 1.44858882e-01, 6.63077315e-02, - 5.01059400e-01, 5.63884027e-01, 6.06887379e-01, 4.28211486e-01, - 6.73317074e-01, 1.64045058e-01, 3.91440262e-01, 8.80823336e-01, - 9.77298198e-01, 8.09425940e-01, 2.75909039e-01, 6.87867004e-01, - 4.31588607e-01, 4.67022700e-01, 5.89732658e-01, 7.31947510e-01, - 6.96354914e-01, 8.00263791e-02, 8.58996981e-01, 9.18389162e-01, - 2.96541314e-01, 3.17287244e-01, 2.24364202e-01, 7.58922521e-01, - 1.42886490e-01, 8.82789350e-01, 1.24438888e-02, 4.36305082e-01, - 8.40564499e-01, 5.14350046e-01, 3.53721806e-01, 7.54399467e-01, - 5.82851470e-01, 1.88329237e-01, 1.45590832e-01, 8.21202267e-01, - 4.07728003e-01, 5.79598930e-01, 5.88699662e-01, 8.13982852e-02, - 7.24101733e-01, 8.33166970e-02, 3.87799867e-01, 2.46674389e-01, - 8.50157642e-01, 5.10641951e-01, 2.47450744e-01, 7.31373513e-01, - 4.77583217e-01, 7.66172459e-01, 9.79793524e-01, 3.22170303e-01, - 7.69627578e-02, 5.96656107e-02, 3.75742821e-01, 4.13440636e-01, - 7.79305266e-01, 1.25088208e-01, 2.92053731e-02, 2.15121750e-01, - 9.27342881e-01, 9.27913992e-01, 5.58917456e-02, 2.73624253e-01, - 7.15506935e-01, 9.47043043e-01, 7.67851199e-01, 6.16052357e-01, - 5.04896165e-01, 1.91733830e-02, 9.11800664e-01, 3.26693749e-01, - 9.51929752e-01, 9.96364078e-01, 9.38893264e-01, 1.70436991e-01, - 2.15993682e-01, 8.81286026e-01, 2.40946280e-01, 6.00209011e-01, - 8.25817074e-01, 9.21595296e-01, 4.19138587e-01, 1.26089706e-01, - 5.45860338e-01, 2.49540348e-01, 9.38377778e-01, 4.90773058e-01, - 2.05905959e-01, 8.86396941e-02, 5.98758647e-01, 7.43958873e-01, - 5.11353848e-01, 9.06709409e-02, 4.20667261e-01, 1.62617320e-01, - 2.03806853e-01, 6.05816851e-01, 4.53797145e-01, 8.09602417e-02, - 6.54555481e-01, 9.19473336e-01, 7.90394742e-01, 1.10089574e-01, - 2.79094074e-02, 1.25150237e-01, 9.12672215e-01, 1.45895379e-01, - 4.05436418e-01, 3.63703747e-01, 2.52415683e-01, 7.78621136e-01, - 8.61324257e-01, 4.72151442e-01, 1.84795053e-01, 1.85572552e-01, - 9.30135884e-01, 2.97275684e-01, 8.06360319e-01, 7.10946726e-01, - 9.31014499e-01, 2.89522462e-01, 6.94432074e-01, 2.10209938e-01, - 4.19736192e-01, 9.37331626e-02, 1.43395136e-01, 2.71813950e-01, - 6.73682887e-01, 9.85545132e-01, 4.57019493e-01, 1.71615789e-01, - 6.50504376e-01, 7.19711026e-01, 7.61462110e-01, 2.74179207e-01, - 1.97967425e-02, 3.00849114e-01, 7.44025519e-01, 6.50661539e-01, - 8.45976633e-01, 5.73840375e-01, 2.12743148e-01, 1.21179424e-02, - 7.78704599e-01, 4.88697254e-01, 7.01110481e-01, 5.10569194e-02, - 3.32610269e-01, 5.48771905e-01, 7.69934632e-01, 5.53739089e-01, - 2.84435006e-01, 6.37823152e-01, 6.53037686e-01, 2.22101098e-01, - 8.01821047e-01, 2.41632157e-01, 3.67283323e-01, 6.71363389e-01, - 4.92522835e-01, 5.58951458e-01, 4.95279668e-01, 4.17524798e-01, - 2.82680269e-01, 7.05273743e-01, 4.97451830e-01, 1.85378453e-01, - 7.65216541e-01, 8.14400833e-01, 2.30582481e-01, 5.27812926e-01, - 6.71191707e-02, 7.13459175e-02, 4.25990016e-01, 2.69332594e-01, - 3.64065055e-01, 6.13207224e-01, 6.54219128e-03, 1.92975201e-01, - 4.04577739e-01, 8.07318510e-01, 6.86850738e-01, 1.88811204e-01, - 3.28074974e-01, 4.16432662e-01, 5.08629789e-02, 1.78805423e-01, - 4.38318656e-01, 2.63040373e-01, 4.38472169e-01, 1.03841694e-01, - 9.58585602e-01, 9.66770564e-01, 3.84663514e-01, 8.97998695e-01, - 8.90662562e-01, 7.49077534e-01, 4.84078317e-01, 7.82234229e-01, - 9.30449711e-01, 3.38727778e-01, 1.73964968e-01, 6.82044981e-01, - 7.02122165e-01, 3.79070306e-01, 2.49612241e-01, 2.08405008e-02, - 8.05092459e-01, 1.57284560e-01, 5.91389808e-02, 3.83195325e-01, - 8.89476629e-01, 2.56531357e-01, 8.15103159e-01, 5.06856367e-01, - 2.47126190e-01, 1.52176371e-01, 3.79095646e-01, 3.19186802e-02, - 5.01105511e-01, 4.50405879e-01, 3.21774373e-01, 8.09024282e-01, - 3.46115199e-01, 5.26717641e-01, 6.37729593e-01, 5.31478634e-01, - 2.32021169e-01, 3.90873089e-01, 5.32944586e-03, 3.64276517e-03, - 2.27834546e-01, 3.69192673e-01, 3.35594527e-02, 8.00989203e-01, - 8.05845643e-01, 2.16534405e-01, 5.39999970e-01, 7.84868427e-01, - 5.25406153e-01, 9.27249061e-01, 8.92506145e-01, 2.20461272e-01, - 7.80199844e-01, 8.64680944e-01, 9.78627472e-01, 3.81483734e-01, - 3.12434676e-01, 2.04898313e-01, 1.73629115e-01, 2.15692299e-01, - 7.80958721e-01, 1.51202230e-01, 1.69168895e-01, 2.15583217e-01, - 3.44120865e-01, 4.88521616e-02, 3.31308723e-01, 1.37062472e-01, - 6.50381691e-01, 1.88296372e-01, 9.34046820e-01, 7.30696527e-01, - 9.30405829e-03, 5.99018954e-01, 3.12655109e-01, 4.61871480e-01, - 7.65057148e-01, 7.79658279e-01, 2.25162670e-01, 9.37780078e-01, - 1.64880929e-01, 4.91960732e-01, 8.09264576e-01, 6.42863915e-01, - 3.25077074e-01, 9.73669255e-01, 4.09034971e-01, 6.07480779e-01, - 1.83313776e-01, 3.86817713e-01, 8.14587592e-01, 3.13004183e-01, - 9.89656700e-01, 9.55616603e-01, 6.42334501e-01, 2.57652921e-01, - 5.95720064e-02, 1.30968950e-01, 2.42594329e-01, 7.52288037e-01, - 3.63044859e-01, 6.45670237e-01, 6.22836299e-01, 8.79067557e-01, - 6.48974979e-04, 6.91664945e-01, 6.87863458e-01, 3.71855520e-01, - 4.02740498e-01, 3.88189326e-01, 6.72183816e-01, 3.73681540e-01, - 7.43587826e-01, 5.23862689e-02, 7.00812999e-01, 8.92570144e-01, - 8.86718049e-01, 1.53632573e-01, 3.69305544e-01, 7.43666709e-01, - 9.52462318e-01, 2.85450411e-02, 3.09484190e-01, 6.09192606e-01, - 4.81734621e-01, 2.31387310e-01, 4.13994788e-01, 3.00968231e-01, - 3.40759084e-01, 4.98786943e-01, 6.85560874e-01, 7.82722760e-01, - 6.27622972e-01, 5.96122860e-01, 3.17137379e-01, 9.30014080e-01, - 3.31774171e-01, 6.98475397e-01, 4.30631692e-01, 7.57323636e-01, - 8.72939052e-01, 5.98425737e-01, 1.52484889e-01, 6.77486994e-01, - 1.56680174e-01, 8.38184526e-01, 7.05223637e-02, 6.32973781e-01, - 5.67406256e-01, 1.05895757e-01, 2.05018894e-01, 6.45525360e-01, - 8.53119159e-01, 2.58419660e-01, 7.36201227e-01, 1.36931145e-01, - 5.57804729e-01, 8.88445302e-01, 6.18788759e-01, 4.40342525e-02, - 4.48816112e-01, 3.55887574e-01, 2.79451134e-01, 1.94955589e-01, - 1.49149324e-01, 9.26957117e-01, 5.94401777e-01, 4.34953168e-01, - 1.72150495e-01, 6.92512560e-01, 6.25659912e-01, 3.53498143e-01, - 4.71827291e-01, 5.48081618e-01, 6.63612391e-01, 7.77597371e-01, - 6.16132267e-01, 2.08793095e-01, 6.54370435e-01, 1.43840575e-02, - 9.26190660e-01, 4.56657569e-01, 1.34607758e-01, 8.46929024e-01, - 1.35479425e-01, 2.73481937e-01, 7.17504372e-01, 6.37246114e-01, - 8.73057171e-02, 1.18451214e-01, 4.87062980e-01, 4.68357032e-01, - 8.14067903e-01, 4.51290963e-02, 8.29995544e-01, 6.92731492e-01, - 4.48054234e-01, 8.08294511e-01, 4.38437815e-01, 9.73087600e-01, - 4.00556362e-01, 2.69210482e-01, 1.90812992e-01, 5.51737526e-01, - 8.09240931e-01, 7.02383255e-01, 9.15284278e-01, 4.71743432e-01, - 4.59917451e-01, 8.27426537e-02, 2.45649835e-02, 3.69984986e-01, - 2.26854883e-01, 1.08020133e-02, 3.29332615e-01, 7.77787273e-01, - 1.93492145e-01, 1.26887826e-01, 2.05285278e-01, 8.06330950e-01, - 3.36846101e-01, 4.28305953e-01, 4.46631616e-01, 1.83568397e-01, - 2.66010074e-01, 1.65533118e-01, 1.97149723e-01, 5.32596310e-01, - 1.31690898e-01, 1.97358686e-01, 3.60311616e-01, 2.34873690e-03, - 4.48739574e-01, 9.42011656e-02, 5.54537272e-01, 5.71754325e-01, - 4.42570791e-01, 7.23765411e-01, 1.68230254e-01, 1.08387844e-01, - 5.63240383e-01, 4.01449664e-02, 7.61878137e-01, 1.84468654e-01, - 7.27330001e-01, 5.70071191e-01, 4.30589309e-01, 8.06933802e-01, - 7.63083913e-01, 4.57054100e-02, 4.22801640e-02, 2.98273838e-01, - 9.94959222e-02, 5.37861705e-01, 9.47728339e-01, 2.35664881e-01, - 9.13932722e-01, 5.27830511e-01, 6.74554633e-01, 8.57226688e-01, - 5.69486299e-01, 5.96239075e-01, 3.44143844e-01, 7.71420730e-01, - 4.03462919e-01, 9.37676468e-01, 6.77939033e-01, 2.94911434e-01, - 8.60944883e-01, 3.97559830e-01, 8.86311983e-01, 9.38773684e-01, - 7.48799949e-01, 2.97265126e-02, 1.91238378e-01, 6.70884380e-02, - 5.78494516e-01, 8.66223057e-01, 5.15415199e-01, 5.97494999e-01, - 1.59946407e-01, 7.89974807e-01, 2.14214317e-01, 7.44879854e-01, - 9.91802395e-01, 8.80220536e-01, 3.98768117e-01, 3.17062606e-01, - 7.43774361e-01, 1.06819069e-01, 1.19235994e-01, 4.66647578e-01, - 4.82252315e-01, 6.63605732e-01, 9.32703913e-01, 1.38701279e-01, - 7.68670880e-01, 7.74230520e-01, 1.86931163e-01, 1.70265692e-01, - 2.75324570e-01, 6.57024567e-01, 9.27178040e-01, 3.24600460e-01, - 2.04220815e-01, 2.07875855e-01, 2.46589386e-02, 1.38795806e-01, - 5.90669097e-01, 8.46731862e-01, 5.01410464e-01, 1.45896367e-01, - 8.23831270e-01, 4.14099435e-01, 9.71332618e-02, 2.90665493e-01, - 5.16384862e-01, 7.81727718e-01, 4.07094101e-01, 4.70877992e-01, - 1.01125711e-02, 3.16454365e-01, 3.82201931e-01, 1.52362350e-01, - 7.28666989e-01, 5.09648353e-01, 2.24362272e-01, 7.93638860e-01, - 8.08595046e-01, 6.35321300e-01, 4.17604409e-01, 8.82336315e-01, - 6.55471605e-01, 9.06895005e-02, 5.25419591e-01, 5.03960948e-01, - 3.50978545e-01, 5.67369898e-01, 2.43048693e-01, 9.29878699e-01, - 2.52345597e-01, 8.11768754e-01, 8.37755411e-02, 5.81591995e-01, - 9.83338281e-01, 4.08169290e-01, 1.67416200e-02, 4.52875430e-01, - 2.35908133e-01, 9.29729555e-01, 3.01862977e-01, 2.32592566e-01, - 5.50182274e-01, 5.94175838e-01, 9.11763820e-01, 4.88732970e-01, - 5.82374445e-02, 5.07425182e-01, 3.97872802e-01, 8.75702431e-01, - 9.26584641e-02, 1.34032927e-01, 8.65220290e-01, 4.77646068e-01, - 5.64651160e-01, 5.63868203e-01, 7.01066889e-01, 9.99257628e-01, - 7.93438387e-01, 7.78084453e-01, 3.83886275e-01, 1.32247747e-01, - 4.56877338e-01, 9.40869768e-01, 1.36509984e-01, 2.29776542e-01, - 5.43033288e-01, 2.51027044e-01, 4.63625930e-01, 6.51180968e-01, - 2.84967568e-01, 1.34521984e-01, 6.69720541e-01, 5.79746270e-02, - 6.81434555e-01, 8.19918480e-01, 1.91151688e-01, 4.21222853e-01, - 7.44794385e-01, 5.62816145e-01, 4.80949879e-01, 6.63528890e-01, - 9.78588328e-01, 2.46133367e-01, 5.91653223e-01, 4.53955601e-01, - 4.34925991e-01, 7.95123585e-01, 2.32427310e-01, 2.27812208e-01, - 1.07205790e-01, 1.02686916e-01, 7.28310993e-02, 2.78261852e-01, - 2.68999714e-01, 1.66088784e-01, 3.03924331e-01, 4.55757123e-01, - 6.97771791e-01, 4.21998035e-01, 7.54431832e-01, 9.88895379e-01, - 5.97588223e-01, 7.77827250e-01, 7.77500552e-01, 7.03786443e-01, - 8.22440262e-01, 5.29597210e-01, 4.36723859e-01, 2.61172795e-01, - 4.35589756e-02, 8.84028111e-01, 5.20544547e-01, 4.22808978e-01, - 5.45181312e-01, 3.22776591e-01, 3.86414085e-01, 9.99154375e-02, - 5.46774851e-01, 6.10197494e-01, 3.16390676e-02, 1.42365823e-01, - 9.28158768e-01, 5.34010927e-01, 1.72812266e-01, 9.62072403e-01, - 6.07521297e-01, 8.16682161e-01, 2.81779552e-01, 4.89829310e-01, - 9.76036227e-02, 2.49798366e-01, 8.50868597e-01, 5.97667258e-01, - 3.39458934e-01, 3.61594764e-01, 3.80919254e-01, 6.61079185e-01, - 9.97603734e-01, 9.09711271e-01, 6.27221370e-01, 6.22777737e-01, - 7.68377872e-01, 6.56516663e-01, 2.25970216e-01, 9.65843632e-01, - 5.77998070e-01, 1.50513870e-01, 7.88508245e-01, 8.82018262e-01, - 2.76371417e-01, 4.73529010e-01, 5.71800915e-02, 4.89584218e-01, - 1.58490570e-01, 3.42111655e-01, 3.48976136e-01, 1.44284027e-01, - 2.22259783e-01, 2.20498807e-01, 7.23087804e-01, 5.17512078e-01, - 5.65352234e-01, 2.97036670e-02, 1.47812718e-01, 6.02454544e-02, - 3.32616659e-01, 1.87872302e-01, 4.76274692e-01, 1.99111440e-02, - 8.07035806e-01, 7.84594619e-01, 9.45455012e-01, 5.39322469e-01, - 4.70902384e-01, 7.79997446e-01, 7.86715314e-01, 7.91430847e-01, - 3.84430392e-01, 6.49550123e-01, 8.03483297e-01, 2.35005171e-01, - 2.93060411e-01, 5.31369131e-01, 7.98171439e-01, 4.49250456e-01, - 1.54089399e-01, 8.06936625e-01, 6.39637642e-02, 1.36853554e-01, - 5.09745299e-01, 8.93579563e-01, 6.32363365e-01, 8.65776056e-02, - 8.46022663e-01, 9.78977986e-01, 1.47910911e-01, 2.79207510e-01, - 7.08750221e-01, 3.08393344e-01, 3.35176457e-02, 7.81951392e-01, - 6.79692719e-02, 1.05858743e-01, 6.66655250e-01, 9.96118373e-01, - 2.33087251e-01, 8.49960603e-01, 6.61580142e-02, 2.35052199e-01, - 5.37827220e-01, 5.40735552e-01, 9.53034646e-01, 5.48703907e-01, - 2.42244973e-01, 6.53147914e-01, 4.93824069e-02, 3.00251928e-01, - 7.89499915e-01, 9.67129119e-01, 5.41588563e-01, 2.05451025e-01, - 2.16913899e-01, 2.63927483e-01, 8.40947650e-01, 7.94181582e-02, - 5.76829660e-01, 5.35626666e-01, 1.95532371e-01, 8.71653894e-01, - 3.80292233e-01, 6.40770559e-01, 7.07799130e-01, 1.95603700e-01, - 4.37961828e-01, 1.95078268e-01, 8.46076613e-01, 4.21713362e-01, - 6.80019446e-01, 1.45723452e-02, 5.78566880e-01, 4.63484866e-01, - 6.62339714e-01, 6.02328370e-01, 4.48952916e-02, 9.56569583e-01, - 9.23635181e-01, 3.96692622e-01, 9.19312566e-02, 9.88443936e-01, - 3.88401164e-01, 5.11607845e-01, 5.52134003e-02, 6.33146212e-01, - 5.14667745e-01, 5.00996886e-01, 9.21919280e-01, 6.57929777e-01, - 7.30453664e-01, 2.67124774e-01, 8.39803649e-01, 5.94649771e-01, - 5.20037425e-01, 6.13862103e-01, 4.24800132e-01, 8.31986162e-01, - 5.45384318e-02, 5.69380895e-01, 5.25750994e-01, 3.64508777e-01, - 5.90030365e-01, 9.52076470e-01, 1.12719576e-01, 3.29530138e-01, - 1.06193364e-01, 5.69039285e-01, 4.82057358e-01, 8.19919084e-02, - 8.56077223e-01, 8.37346876e-02, 8.06609845e-01, 6.16729834e-01, - 5.24836850e-01, 7.70617407e-01, 7.64831307e-01, 8.96567554e-01, - 5.24420117e-01, 2.77623259e-01, 3.22800389e-01, 8.56595438e-01, - 7.97408897e-01, 9.84336322e-01, 6.05872705e-01, 1.72064448e-01, - 3.39865874e-01, 1.07895600e-01, 6.35505667e-01, 7.17785020e-01, - 4.54956674e-02, 8.40944711e-01, 9.09263046e-01, 7.23253622e-01, - 6.08397636e-01, 4.28223693e-01, 3.49143495e-01, 5.17343768e-01, - 3.03931241e-02, 2.58809922e-01, 6.26347058e-01, 2.58317379e-01, - 7.70094729e-02, 4.90677171e-01, 6.23578413e-01, 7.39323402e-01, - 7.86430216e-01, 1.95871033e-01, 9.59352018e-01, 9.48050021e-01, - 4.04923161e-01, 5.48466997e-01, 6.32778119e-01, 9.27004568e-01, - 4.60867852e-01, 6.18367404e-02, 4.49117997e-01, 5.72517365e-02, - 7.42512152e-01, 8.52078457e-01, 9.18500080e-01, 7.53443248e-01, - 8.79991036e-01, 7.73933267e-01, 8.12208158e-01, 5.08698053e-01, - 4.83453257e-01, 1.40564155e-01, 4.63751858e-01, 6.94391333e-02, - 5.67141354e-01, 4.81644035e-01, 7.99300967e-01, 3.42458925e-01, - 7.13255922e-01, 7.30373655e-01, 2.54026166e-01, 8.92656780e-01, - 3.43299490e-01, 2.91557217e-01, 7.04476359e-01, 6.38560693e-01, - 5.97876994e-01, 9.14060350e-01, 7.10507406e-01, 5.27871014e-01, - 1.37971080e-03, 8.49668317e-01, 4.03172758e-01, 1.69417224e-01, - 9.15704212e-02, 5.80469353e-02, 2.86447181e-02, 4.22680837e-01, - 2.75320503e-01, 7.19456317e-01, 5.54424190e-01, 4.19628151e-01, - 9.03261398e-01, 2.40076435e-01, 6.24940979e-02, 7.68350219e-01, - 8.16259858e-01, 4.07364240e-01, 1.90892373e-01, 2.24645957e-01, - 2.68513102e-01, 8.59940842e-01, 4.26799814e-01, 9.34924639e-02, - 5.04900452e-01, 6.19869474e-01, 1.39149678e-01, 3.32084425e-02, - 2.04821361e-01, 1.52667263e-01, 7.59186101e-01, 1.77790763e-01, - 5.40029943e-01, 5.39653163e-02, 1.08297347e-01, 1.95635060e-01, - 1.14453063e-01, 3.34717092e-02, 9.73972485e-01, 9.49581829e-01, - 7.09210000e-01, 1.83736580e-01, 7.98625861e-01, 2.06249983e-01, - 8.11163305e-01, 7.09788798e-01, 7.31928595e-01, 7.06239329e-01, - 4.61273623e-01, 1.47860630e-01, 7.97788920e-01, 2.53221786e-02, - 1.08083311e-01, 1.76009409e-01, 4.57938076e-01, 8.47280675e-01, - 9.33968107e-01, 2.36854123e-01, 4.25184701e-01, 6.06357301e-02, - 7.30137098e-01, 1.82268678e-01, 9.19488237e-01, 4.59848807e-02, - 9.82461133e-01, 7.36827770e-01, 3.94792587e-02, 1.05485901e-01, - 9.04068922e-01, 5.89364625e-01, 5.82999420e-01, 9.84180524e-01, - 8.39599561e-01, 8.16253555e-01, 1.88702947e-01, 9.34650148e-01, - 5.54412280e-01, 6.74554821e-01, 7.44570651e-01, 4.93609876e-01, - 3.85316007e-01, 5.88890462e-01, 9.59817567e-01, 6.49085393e-01, - 5.08310855e-01, 6.46559754e-01, 6.26565112e-01, 3.42146898e-01, - 3.88847276e-01, 2.82999302e-01, 3.32617413e-01, 3.60441738e-01, - 6.15696983e-02, 8.09875704e-02, 3.93702137e-01, 9.00132344e-01, - 2.87506971e-01, 5.79431727e-01, 8.15253471e-01, 9.52292387e-01, - 6.68236002e-01, 9.92367542e-01, 9.96548846e-01, 8.44550511e-01, - 8.24719137e-01, 7.65994828e-01, 1.09263635e-01, 6.38947299e-01, - 5.79485650e-01, 1.85070162e-01, 7.27596719e-01, 5.95479534e-01, - 4.17556122e-01, 4.80422572e-01, 6.77294362e-01, 8.18737713e-01, - 8.03728185e-01, 6.29570464e-01, 8.86369135e-01, 9.83240973e-02, - 7.91938800e-01, 4.55609898e-01, 7.42090017e-01, 6.49227163e-01, - 1.38344917e-01, 5.73024319e-01, 1.42592663e-01, 1.47296755e-01, - 9.05088934e-01, 3.32192389e-01, 8.80267050e-01, 3.43224412e-02, - 6.15051147e-01, 3.09894837e-01, 4.48333590e-01, 3.08905528e-01, - 7.19655202e-01, 5.08634603e-01, 7.24210742e-01, 8.49162045e-01, - 7.39923339e-01, 4.28078649e-01, 7.73026762e-01, 5.58670880e-01, - 2.14258147e-01, 2.56797489e-01, 3.64649241e-01, 1.90313112e-01, - 1.59470431e-01, 4.12877241e-02, 1.15591053e-01, 2.61831664e-02, - 4.47307902e-01, 3.46625095e-01, 7.02788265e-01, 1.42473756e-02, - 9.14824501e-01, 8.90997679e-01, 7.89556999e-01, 3.15688565e-01, - 5.47100304e-02, 1.72920709e-01, 6.34539788e-01, 2.66849962e-01, - 3.90958160e-01, 9.91716809e-01, 2.50697140e-01, 2.00590811e-01, - 7.04236260e-01, 8.60993346e-01, 9.60179095e-01, 4.93160964e-01, - 5.64962057e-01, 8.91017606e-01, 3.90111599e-01, 9.18168639e-01, - 5.18288168e-01, 9.37449134e-01, 8.92922549e-01, 8.52365292e-01, - 5.33240791e-01, 6.93511885e-02, 6.13448765e-01, 1.69536026e-01, - 5.34564717e-03, 3.54464573e-01, 1.31301275e-01, 2.49233573e-01, - 7.83740348e-01, 8.27472899e-01, 1.02076185e-01, 2.13321521e-01, - 8.39823926e-01, 2.96124623e-01, 5.32126642e-01, 9.37173836e-03, - 3.32925900e-01, 8.61626197e-01, 1.59908436e-01, 9.54738379e-01, - 3.71265604e-01, 4.63355901e-01, 8.17367258e-01, 5.54249630e-01, - 3.91232958e-01, 2.83533793e-01, 3.76686578e-02, 8.18705432e-01, - 1.14308247e-01, 1.35529656e-01, 3.56726257e-01, 3.82159013e-01, - 1.90242846e-01, 6.27398094e-01, 7.42727283e-01, 2.53052257e-01, - 2.92263497e-01, 8.36861838e-01, 8.80117657e-01, 4.24251998e-01, - 2.42857082e-01, 3.26912947e-01, 2.38978271e-02, 3.87288511e-01, - 8.38786160e-01, 2.76140434e-02, 1.41603539e-01, 2.45213250e-01, - 9.01979435e-01, 7.98300877e-01, 6.28114620e-02, 3.39538356e-01, - 9.98955922e-01, 8.83984654e-01, 3.25924686e-02, 2.66477681e-01, - 9.87529006e-01, 3.94806394e-01, 1.79714717e-02, 7.22094984e-01, - 8.43448057e-01, 2.97094385e-01, 6.30082031e-01, 4.69114638e-01, - 7.56449205e-01, 5.39852806e-01, 6.64231525e-01, 2.56561259e-01, - 1.69032579e-01, 6.35520653e-01, 5.32374143e-01, 2.41790269e-01, - 1.31880241e-01, 7.21668905e-01, 8.49549657e-01, 9.51179163e-01, - 9.31236210e-01, 1.60580056e-01, 4.81987713e-02, 8.55740104e-01, - 2.33510121e-01, 8.06852287e-01, 8.36335316e-01, 4.08700026e-02, - 3.01354537e-01, 7.04597923e-01, 5.72346977e-01, 6.20919695e-01, - 5.61694124e-01, 7.33794430e-01, 6.94145175e-01, 4.53505475e-01, - 7.55109956e-01, 8.14496494e-01, 6.46203394e-01, 4.60737495e-01, - 6.54667111e-01, 5.35883231e-01, 9.59617583e-01, 7.20299072e-01, - 9.15563119e-02, 7.21026109e-01, 4.67450149e-01, 7.34462257e-01, - 7.99462181e-01, 2.68883715e-01, 9.28422756e-01, 3.00536442e-01, - 7.14940787e-01, 6.83090883e-01, 1.76575309e-01, 5.80842227e-02, - 8.21636031e-01, 7.98096674e-02, 4.11193499e-01, 5.52466051e-01, - 7.67632729e-01, 4.98006389e-01, 4.32751169e-01, 2.97660033e-01, - 6.00292000e-01, 3.13053918e-01, 7.06950914e-01, 7.73032205e-01, - 3.39058015e-01, 7.45874867e-01, 2.94171799e-01, 2.87739192e-01, - 3.66448107e-01, 7.90110213e-01, 9.46773396e-01, 6.61030817e-01, - 8.28805709e-01, 3.68350359e-01, 9.01018421e-01, 5.58504106e-01, - 3.87886907e-01, 4.53400553e-01, 5.36041878e-01, 9.40252927e-01, - 6.32877657e-01, 8.17582446e-01, 6.60348688e-01, 7.84982408e-01, - 4.70946735e-01, 4.22792289e-01, 1.15773673e-01, 7.85006539e-01, - 6.60265886e-01, 8.06774887e-01, 4.58476060e-01, 5.72138920e-01, - 9.41565763e-02, 3.07655221e-01, 7.62754808e-01, 7.59367227e-02, - 5.02760941e-01, 3.31379403e-02, 6.97535587e-01, 6.63730619e-01, - 8.13759447e-01, 5.80630029e-02, 9.90930123e-01, 8.62673324e-01, - 7.59293522e-01, 8.87188097e-01, 6.15587858e-01, 4.74667163e-01, - 5.12807468e-01, 9.86933916e-01, 7.91295121e-01, 3.03786248e-01, - 9.72577890e-01, 5.18621477e-01, 1.42679940e-01, 6.23338740e-01, - 6.40711239e-01, 9.89085235e-01, 6.54985281e-01, 7.57553525e-01, - 6.65357528e-01, 4.80734243e-01, 9.40583203e-01, 4.85679346e-01, - 5.79304551e-01, 3.25099620e-01, 2.59389691e-01, 5.71960521e-01, - 2.63128068e-01, 4.61009923e-01, 4.47025639e-02, 3.52733473e-02, - 2.77707989e-01, 2.37116023e-01, 8.84448709e-01, 3.04657122e-02, - 2.38680052e-01, 7.03965210e-01, 8.58533546e-01, 5.75351731e-01, - 9.72826173e-01, 7.90426471e-01, 8.22624728e-01, 8.53964640e-01, - 7.70330678e-01, 1.92417498e-01, 2.86306961e-01, 3.65725047e-01, - 6.34083990e-01, 4.22059202e-01, 8.37637313e-01, 7.01322018e-01, - 9.16658031e-01, 9.59801062e-01, 8.27736271e-01, 3.75673003e-01, - 4.94315067e-01, 4.48762864e-01, 5.99333709e-01, 7.00869026e-01, - 5.90852451e-01, 9.99524217e-01, 6.62704721e-02, 2.20955862e-01, - 6.88692705e-01, 2.94846178e-01, 8.03357822e-01, 9.87092429e-01, - 1.39423869e-01, 4.11924707e-01, 5.67289118e-01, 6.38548666e-02, - 5.46612866e-01, 9.99390104e-01, 9.24665265e-02, 5.65808119e-01, - 4.33145041e-02, 2.85775584e-01, 3.05153883e-01, 3.35801307e-01, - 4.47778090e-01, 7.92308286e-01, 5.14027224e-01, 5.41968344e-01, - 8.49974156e-01, 4.95159145e-01, 3.41339561e-03, 2.02271820e-01, - 9.56276383e-02, 4.90971131e-01, 5.21295786e-01, 5.42892847e-01, - 6.26040319e-01, 8.85220690e-02, 2.99885797e-01, 7.68347901e-01, - 3.78608811e-02, 8.21087965e-01, 3.78189165e-01, 4.69839343e-01, - 8.48830049e-01, 2.20051672e-01, 1.84346607e-01, 3.35279438e-01, - 2.22260001e-01, 2.11140889e-01, 2.65866059e-01, 3.79417370e-01, - 7.32603485e-02, 2.02974235e-02, 3.17654644e-01, 3.19123230e-01, - 5.10658015e-01, 7.94214613e-01, 5.87610392e-01, 5.71706229e-01, - 5.82713135e-01, 9.65731692e-01, 7.47778571e-01, 1.06282990e-01, - 4.61777308e-01, 5.07590624e-01, 1.55575790e-01, 8.56965796e-01, - 5.41864428e-01, 2.81549341e-01, 6.72815889e-01, 1.98717142e-01, - 4.34212604e-01, 6.64007833e-01, 8.06428943e-01, 9.72578580e-01, - 8.73359588e-01, 3.59833169e-01, 1.52169598e-01, 2.36812799e-01, - 3.17308214e-01, 4.26665454e-02, 1.22512713e-01, 4.05887410e-01, - 3.94635327e-01, 3.68368934e-02, 3.49016215e-01, 8.38410709e-01, - 9.23341580e-01, 8.78149070e-01, 6.72170048e-01, 4.79080022e-01, - 1.76197102e-01, 9.70706114e-01, 7.46602218e-01, 7.83664886e-01, - 4.36771835e-01, 6.58181637e-01, 3.38112165e-01, 8.31991302e-01, - 6.69758962e-01, 7.19515257e-01, 9.63824555e-01, 7.04025455e-01, - 8.07361051e-03, 8.22656090e-01, 6.68232709e-01, 9.86633387e-01, - 9.31587947e-01, 1.89205641e-01, 8.31760559e-01, 3.99644613e-01, - 5.49750466e-01, 3.26770512e-01, 6.23341186e-01, 3.34890896e-02, - 1.25361895e-02, 6.75823497e-01, 8.52968623e-01, 2.28659041e-01, - 9.92708833e-01, 8.85488472e-01, 9.92329920e-01, 5.57386714e-01, - 2.35817451e-01, 7.40349073e-01, 5.38877219e-01, 5.74460419e-01, - 7.72192466e-01, 7.64336567e-01, 6.74542062e-01, 1.62896787e-01, - 2.61742322e-01, 5.72680831e-01, 6.99712111e-01, 9.74436138e-01, - 2.80347461e-01, 6.08853032e-01, 6.91366377e-01, 7.31669555e-01, - 3.50676919e-01, 6.92695805e-01, 2.48933946e-01, 6.05741327e-01, - 9.32503295e-01, 5.24577289e-01, 8.91639308e-01, 2.74987654e-01, - 3.64413512e-01, 1.56359440e-01, 5.09185290e-01, 4.48479242e-01, - 7.90023320e-01, 1.24554957e-01, 6.21422182e-01, 5.52338075e-02, - 3.68692332e-02, 2.00019543e-01, 9.27458438e-01, 3.92990899e-01, - 4.21673525e-02, 7.70416563e-01, 8.86621220e-01, 7.55030905e-01, - 2.13003787e-01, 5.20746996e-01, 1.77610089e-01, 2.76658040e-01, - 5.34957940e-01, 5.07861890e-01, 9.39110894e-01, 5.49537100e-01, - 8.68028448e-01, 2.16525558e-01, 1.97140706e-01, 3.49594827e-01, - 3.54786930e-02, 1.25642055e-01, 3.23148854e-01, 6.59144483e-01, - 6.73652474e-02, 8.20217976e-01, 1.86125028e-01, 2.72470316e-01, - 4.53537023e-01, 7.38119238e-01, 4.63841811e-01, 6.22931735e-01, - 4.95265620e-01, 6.14475291e-01, 3.51725884e-01, 5.56822091e-02, - 4.21759674e-01, 5.24325777e-01, 2.66436258e-01, 5.01266626e-01, - 8.27531598e-03, 4.17005354e-01, 9.39479931e-01, 8.76098365e-01, - 8.88392722e-01, 2.85271817e-01, 8.34833471e-01, 5.64586137e-01, - 7.77844836e-02, 2.61251905e-01, 6.48985720e-01, 6.03212973e-01, - 8.78170613e-01, 2.77922683e-01, 6.65340300e-01, 2.95590225e-01, - 1.94139083e-01, 9.97260166e-01, 4.27979004e-01, 1.46587201e-01, - 9.14098680e-01, 5.54870417e-01, 3.04025847e-02, 9.57974410e-01, - 8.87549419e-01, 7.09466012e-01, 2.71466554e-01, 9.92152475e-02, - 9.75994038e-01, 2.38892332e-01, 9.13048467e-01, 9.46067934e-01, - 4.29107264e-01, 4.94560570e-01, 2.46311003e-01, 8.04130839e-01, - 3.49338353e-01, 8.20269578e-01, 2.41718153e-01, 8.05506434e-01, - 9.83580808e-01, 5.09911997e-02, 7.40563267e-02, 2.74853859e-02, - 3.48562564e-02, 8.43584418e-01, 3.32971919e-01, 2.23330229e-01, - 6.81656029e-01, 8.93232502e-02, 9.14066333e-02, 3.51538343e-01, - 7.69332041e-01, 4.20118553e-01, 6.06463056e-01, 4.85176247e-01, - 3.34052122e-01, 8.35118023e-01, 5.06263115e-02, 7.02983225e-01, - 5.46352422e-01, 9.84490191e-01, 7.13189407e-01, 2.44420584e-01, - 2.38207534e-01, 5.19293675e-01, 1.70908671e-01, 4.27618052e-01, - 5.29870241e-02, 8.17518931e-01, 4.27241004e-01, 2.56208965e-01, - 3.77940215e-01, 7.98871644e-02, 3.72998241e-01, 2.33430622e-01, - 7.66957776e-01, 3.37328625e-01, 8.43431734e-01, 3.14068010e-01, - 7.11371765e-01, 6.02345944e-01, 3.68904626e-01, 8.64697423e-01, - 4.07108753e-01, 2.16111030e-02, 2.14349295e-01, 7.70115577e-01, - 2.86861456e-01, 9.58923829e-01, 5.04839384e-01, 4.26919575e-01, - 3.44502146e-01, 5.30290335e-01, 8.84382228e-01, 5.75249467e-01, - 2.15944689e-01, 1.68629113e-01, 7.18216688e-01, 8.98706455e-01, - 7.56085076e-01, 1.69716123e-01, 6.92024773e-01, 2.71360510e-01, - 4.09984490e-01, 2.65937395e-01, 7.22243688e-01, 5.47279785e-01, - 6.32263300e-01, 6.94593903e-02, 9.10246244e-01, 9.29194032e-01, - 1.04722871e-01, 7.40824097e-01, 9.55011084e-01, 3.38004297e-01, - 6.15096449e-01, 4.47571950e-01, 6.10133913e-01, 7.33553351e-03, - 2.00805149e-01, 4.48893133e-01, 7.85674044e-01, 9.21148806e-01, - 9.50452261e-01, 6.53467376e-01, 1.99568002e-01, 2.62917738e-01, - 3.36655772e-01, 3.26309328e-01, 9.64056551e-01, 6.34673709e-01, - 8.84606346e-01, 1.72232592e-01, 5.06183907e-01, 7.48059744e-01, - 1.11917738e-01, 2.13407378e-01, 8.46829291e-01, 7.08922828e-02, - 4.75820652e-04, 9.80558932e-01, 9.03841391e-01, 3.61414975e-01, - 3.94521239e-01, 3.06723640e-01, 1.86482445e-01, 3.23159685e-01, - 3.04486261e-01, 2.17553013e-01, 2.30987652e-01, 1.34657490e-01, - 8.36244609e-01, 4.30954358e-01, 3.36325080e-01, 4.64812396e-01, - 3.59119545e-01, 4.46583657e-01, 4.11849902e-01, 7.91683705e-01, - 9.05923969e-01, 9.78355471e-01, 6.00500903e-01, 6.58112732e-01, - 9.82635217e-01, 5.17340547e-01, 2.80000378e-01, 9.73667686e-02, - 7.02810620e-01, 2.36811151e-01, 3.72802331e-01, 6.13680212e-01, - 8.59358537e-01, 7.07611548e-01, 1.25129327e-01, 6.19772362e-01, - 1.75676032e-01, 4.61162472e-01, 8.86568485e-01, 5.44900181e-01, - 5.43623344e-01, 5.99687827e-01, 6.05290895e-01, 9.55831196e-01, - 7.43341490e-01, 1.21098972e-01, 1.72510401e-01, 6.75851447e-01, - 8.05463584e-01, 4.90538976e-02, 5.79412266e-01, 9.46759569e-01, - 2.25075578e-01, 9.72467123e-01, 8.82391429e-01, 6.36069484e-01, - 2.62940963e-01, 5.39028357e-01, 7.97688315e-01, 6.92736261e-01, - 9.04445568e-01, 1.17347367e-01, 9.74424315e-01, 6.86943402e-01, - 2.55646187e-01, 8.10824021e-01, 3.77618845e-02, 4.54739412e-01, - 1.30133574e-01, 8.64149700e-01, 3.36050621e-01, 5.20979198e-01, - 1.06564453e-01, 8.25132673e-01, 3.24691291e-01, 5.68278962e-01, - 9.96891990e-03, 2.53055416e-01, 6.92810702e-02, 5.73506182e-01, - 5.98755884e-01, 2.70908536e-01, 1.16946732e-01, 9.00115871e-01, - 8.99171023e-01, 1.49706602e-01, 9.90410630e-01, 5.52884767e-01, - 2.23368805e-01, 4.24984034e-01, 3.15279787e-01, 4.02863385e-01, - 1.32490132e-01, 6.12507969e-01, 7.75470470e-01, 3.03788987e-01, - 8.09816938e-01, 5.51244819e-02, 5.57184003e-01, 4.78323230e-01, - 3.16198852e-01, 4.37246245e-02, 2.00394780e-01, 2.07153216e-01, - 4.35360023e-01, 3.27049535e-03, 5.88090443e-01, 9.87310631e-01, - 4.48000309e-01, 8.26970379e-01, 9.63004400e-01, 5.28054977e-01, - 2.31469302e-01, 8.16195404e-01, 1.11114151e-01, 8.76980575e-01, - 8.79745589e-01, 4.07336830e-01, 7.53084034e-01, 3.42539389e-01, - 4.10135264e-01, 5.49545791e-01, 8.61324025e-02, 9.63889143e-01, - 6.74782766e-01, 1.57750849e-01, 3.69064150e-01, 2.02781018e-01, - 8.98577037e-01, 5.91808176e-02, 4.44658234e-01, 5.09630377e-01, - 8.63433396e-01, 8.07552583e-01, 4.61586958e-01, 3.88508684e-01, - 8.55963808e-01, 1.59259234e-01, 5.67096453e-01, 6.45100269e-01, - 4.23739705e-01, 2.36566610e-01, 5.88852233e-01, 1.42456888e-01, - 6.09449063e-01, 2.91932431e-01, 2.15341330e-01, 8.10063767e-01, - 7.30277737e-01, 5.68174445e-01, 2.26578155e-02, 1.75666393e-02, - 7.42347746e-01, 2.34091828e-01, 9.93016145e-01, 3.71463380e-01, - 5.37628998e-01, 5.15323678e-01, 9.28717897e-01, 3.75234961e-01, - 6.42269116e-01, 2.58183825e-01, 9.39492562e-01, 1.68855727e-02, - 1.46790998e-01, 4.44304313e-01, 8.27096789e-01, 9.65983613e-01, - 6.23461705e-01, 4.62219822e-01, 5.03252364e-01, 9.77850835e-01, - 4.21407294e-01, 7.99087692e-01, 4.24821042e-01, 2.17062611e-01, - 6.03106161e-01, 2.96861607e-01, 8.30823608e-01, 1.95787157e-01, - 6.30261220e-01, 4.78713679e-01, 1.46507778e-01, 3.81508909e-01, - 9.25811504e-01, 6.87689757e-01, 6.54612475e-01, 2.43462597e-01, - 6.85728968e-01, 8.65893047e-01, 1.72877918e-01, 3.09501218e-02, - 8.55966506e-01, 9.34467720e-01, 8.35867579e-02, 3.88607159e-01, - 9.15155385e-01, 6.58913765e-01, 2.42180137e-01, 2.46684840e-01, - 6.36678590e-01, 4.74446255e-01, 9.26442388e-01, 7.82513307e-01, - 3.26607167e-01, 2.56176734e-01, 7.66614295e-01, 3.58891060e-01, - 6.57769693e-01, 9.10220435e-01, 7.69488588e-01, 7.40670425e-01, - 1.71742490e-01, 3.58707520e-01, 6.69410941e-01, 3.46724171e-01, - 2.24290351e-01, 5.53622957e-01, 9.37881088e-01, 5.99370135e-01, - 8.32153059e-01, 7.07144882e-01, 5.76510777e-01, 6.13860514e-01, - 8.69925240e-01, 9.04260751e-01, 7.17822873e-01, 9.41333028e-01, - 9.77852344e-02, 3.10661266e-01, 9.06719929e-01, 4.41852355e-01, - 2.87260615e-01, 4.65262943e-01, 8.51225292e-01, 1.95858580e-01, - 4.60642027e-01, 6.07634181e-01, 8.58294303e-01, 7.04950942e-01, - 3.18351000e-01, 7.04083103e-01, 7.54832971e-01, 2.28850922e-01, - 9.65221365e-01, 1.65974800e-01, 3.33757588e-01, 7.63917161e-01, - 7.95931786e-01, 1.25451562e-01, 9.20205666e-01, 6.93588360e-01, - 2.07615294e-01, 3.67905817e-01, 2.84161666e-01, 8.20995283e-01, - 2.33326835e-01, 4.72732003e-01, 5.37092693e-01, 8.00556071e-01, - 5.66400893e-01, 1.00017828e-01, 3.77833077e-01, 6.18122571e-01, - 8.88109779e-01, 7.06298775e-01, 2.38202240e-01, 8.78992198e-01, - 7.37780946e-01, 3.67454915e-01, 7.89792206e-02, 3.79873213e-02, - 7.56798927e-02, 8.75369367e-01, 9.39321223e-01, 7.85939325e-01, - 4.08066159e-02, 2.12340053e-01, 7.69471008e-01, 1.74381287e-01, - 1.60841016e-01, 7.72649803e-01, 8.16524393e-02, 9.03926140e-01, - 7.65933215e-01, 2.38672182e-01, 2.99578900e-02, 2.47778312e-02, - 7.96387666e-02, 7.15959981e-01, 5.31452267e-01, 1.21193992e-01, - 9.05560889e-01, 7.56699236e-02, 1.00237568e-01, 6.04340484e-01, - 3.41526161e-01, 8.75333335e-02, 5.68548728e-01, 3.21788914e-01, - 9.56745416e-01, 3.71181926e-01, 2.76248909e-01, 9.92589721e-01, - 1.42920537e-01, 7.48649341e-01, 8.43028090e-01, 4.29391774e-01, - 4.38819469e-01, 9.50800680e-01, 4.72544801e-02, 5.66026696e-01, - 7.22736005e-01, 5.04268996e-01, 6.57853778e-01, 9.61713826e-01, - 8.95523497e-01, 3.34435877e-01, 8.97264821e-01, 5.64684560e-01, - 1.99838647e-01, 9.60683345e-01, 7.92005704e-01, 3.23132314e-01, - 5.07424603e-01, 5.28305189e-01, 1.21013320e-01, 7.70779091e-01, - 1.29072351e-01, 1.45333366e-01, 1.40539434e-01, 2.95840404e-01, - 7.65696290e-01, 8.05248438e-01, 1.91378861e-01, 6.25523103e-01, - 8.83920163e-01, 6.55328273e-01, 6.90872602e-01, 3.44399040e-01, - 4.02787192e-01, 9.98515178e-01, 9.64001652e-01, 5.27608302e-01, - 4.22985376e-01, 6.45137599e-01, 2.64982564e-01, 3.55932607e-02, - 1.56578365e-02, 8.94011735e-01, 6.60009637e-01, 4.63266413e-01, - 9.17174867e-01, 5.74679175e-01, 3.80381277e-01, 5.30344006e-01, - 9.16629424e-01, 8.96553125e-01, 9.88238713e-01, 9.71032691e-01, - 6.61241205e-01, 2.53430771e-01, 2.66687645e-01, 2.20269105e-01, - 8.71755269e-01, 3.34287811e-01, 7.18603753e-01, 2.46970751e-01, - 5.89249037e-01, 7.00068234e-01, 6.89398030e-02, 2.33212759e-01, - 8.37047068e-01, 4.55746642e-01, 3.13376759e-01, 3.36671744e-01, - 9.86266611e-01, 4.91239814e-01, 3.08574122e-02, 7.94701934e-01, - 5.66491704e-01, 7.67457763e-01, 9.37298891e-01, 4.78976448e-01, - 9.86544042e-01, 7.02061268e-01, 6.53817701e-01, 3.71155276e-01, - 2.60907578e-01, 5.85319640e-01, 9.45041623e-01, 7.40462655e-01, - 1.11546526e-01, 4.10594828e-01, 1.06975855e-01, 3.84593793e-01, - 9.77971558e-01, 3.08326986e-01, 8.07310177e-01, 3.28507306e-01, - 9.32904076e-01, 4.90315230e-01, 1.88473389e-01, 9.98211022e-01, - 2.00129754e-01, 8.39642213e-01, 7.65678274e-01, 1.80968461e-01, - 5.43392463e-01, 6.61209029e-01, 8.98463227e-02, 9.67827931e-01, - 1.69588308e-01, 2.52317843e-01, 6.71753608e-01, 5.29174070e-01, - 4.90966173e-01, 7.95859952e-01, 8.47774974e-01, 9.90356217e-01, - 7.17803992e-02, 5.01820617e-01, 4.78503791e-01, 1.72398291e-01, - 8.58030440e-01, 3.91881377e-01, 5.05400976e-01, 3.47302950e-01, - 8.97706444e-01, 1.47047957e-01, 1.09276728e-01, 3.85948120e-01, - 6.32160799e-01, 3.09729769e-01, 1.45959889e-01, 6.51738192e-01, - 2.77359906e-01, 6.92773054e-01, 8.14352970e-01, 8.96188714e-01, - 2.39638765e-01, 8.63710492e-01, 1.66139586e-01, 6.03744055e-01, - 1.24088509e-01, 9.15337173e-01, 3.24991685e-01, 6.60493009e-02, - 1.09817591e-01, 8.07880695e-01, 9.71810173e-01, 4.25945929e-01, - 1.20525605e-02, 5.16411392e-01, 2.68513580e-01, 9.24923249e-01, - 4.32181559e-01, 9.68089042e-01, 3.81282468e-01, 4.62766764e-01, - 5.44815631e-01, 8.62732384e-01, 2.15997007e-01, 8.37078836e-01, - 1.66759570e-01, 6.02925213e-01, 4.09434973e-01, 7.82767163e-01, - 8.17678578e-01, 3.35119919e-01, 9.73108659e-01, 9.44013792e-01, - 3.52023720e-02, 2.37726578e-01, 9.08003444e-02, 3.94729051e-01, - 4.66562025e-01, 9.58716767e-01, 9.51111004e-02, 9.03067834e-02, - 9.67253250e-01, 1.34958150e-01, 7.75408263e-01, 2.41508660e-01, - 4.44066115e-01, 8.03780035e-01, 3.31793361e-01, 2.92949631e-01, - 3.84433947e-02, 1.57765046e-01, 1.14735394e-01, 8.39733854e-01, - 7.53977626e-02, 3.78325908e-01, 6.16541477e-01, 2.15293843e-01, - 8.34179433e-01, 3.35038491e-01, 4.71613667e-01, 1.13641679e-01, - 1.61295492e-02, 3.26335647e-01, 5.18397775e-01, 5.61656625e-01, - 4.42681186e-01, 3.02317784e-01, 4.59098700e-01, 4.98011038e-01, - 5.48420488e-01, 2.71047389e-01, 3.06884911e-01, 4.76432724e-01, - 3.64307976e-01, 6.69453523e-01, 8.54892855e-01, 4.92702524e-01, - 1.65759921e-01, 9.45461863e-01, 3.75407124e-01, 7.01633745e-01, - 7.32011928e-01, 9.00117458e-01, 5.35411379e-01, 5.61215090e-01, - 9.54729047e-01, 3.18383819e-01, 7.93318688e-01, 8.83019804e-01, - 6.70023448e-01, 3.04276026e-01, 7.72705160e-01, 1.16462235e-01, - 6.11836183e-01, 5.59790131e-01, 5.53714370e-01, 8.51134658e-01, - 6.33641310e-01, 9.08476844e-01, 1.18270140e-01, 3.55683184e-01, - 3.24686131e-01, 7.62193842e-01, 9.52641604e-01, 5.31009229e-02, - 6.00007976e-01, 6.18481943e-01, 3.89081395e-01, 7.25332074e-01, - 3.70882927e-01, 9.88628705e-01, 8.41353168e-01, 4.00406070e-01, - 4.23043795e-01, 7.36063541e-01, 9.72860479e-01, 1.36609972e-01, - 6.44853627e-01, 5.47117840e-01, 4.08717930e-01, 5.44742362e-01, - 9.86351244e-01, 9.97193796e-01, 2.48848748e-01, 6.77861375e-01, - 6.89598269e-01, 9.26310921e-01, 8.52964325e-02, 7.94844855e-01, - 6.32468893e-01, 7.97472368e-01, 4.90493449e-02, 8.54016131e-02, - 5.30757552e-01, 6.71426051e-01, 6.13413818e-01, 5.30918505e-01, - 2.94998400e-01, 1.16854328e-01, 2.89631219e-01, 8.93798771e-01, - 6.06916939e-01, 6.34586972e-01, 8.04901103e-01, 8.02330018e-01, - 7.79161920e-01, 8.19051757e-02, 8.94049903e-01, 2.21494005e-01, - 7.98238830e-01, 8.98699013e-01, 4.24380388e-01, 8.32058631e-01, - 1.13005616e-01, 2.43128336e-01, 5.76537456e-01, 1.21295230e-01, - 4.40471214e-01, 9.10894263e-02, 4.63586749e-01, 1.54430311e-01, - 1.52645291e-01, 9.30308029e-01, 2.59722999e-01, 9.36238982e-01, - 6.66003428e-01, 4.20867757e-01, 2.63315470e-02, 4.68727306e-01, - 8.50890717e-01, 8.97461649e-02, 5.08052130e-01, 3.43861376e-01, - 6.27334974e-01, 8.00342743e-01, 4.73994538e-01, 9.58824933e-01, - 3.67167179e-01, 3.19473500e-01, 5.74331025e-01, 8.15212512e-01, - 8.76944579e-01, 2.62598053e-01, 9.55549952e-01, 1.84390110e-01, - 2.33745334e-01, 1.37922140e-01, 7.59530653e-01, 5.15519280e-01, - 5.82319374e-01, 4.09600826e-02, 8.48185616e-01, 5.27773620e-01, - 4.03515531e-01, 2.49546221e-01, 2.98413460e-01, 2.67321780e-01, - 9.83392883e-01, 1.65392749e-01, 2.54257615e-01, 8.03826748e-01, - 2.70193424e-01, 6.08416784e-01, 5.68371411e-02, 5.84520953e-01, - 5.32395063e-01, 4.06089193e-01, 6.76055824e-01, 8.15386503e-01, - 9.78666220e-01, 4.56107596e-01, 1.00136326e-01, 1.46995741e-01, - 2.67153710e-01, 6.13216652e-01, 1.50174198e-01, 9.06924786e-01, - 5.21420408e-01, 5.69244153e-01, 4.99491059e-01, 5.36596230e-01, - 5.20118606e-01, 2.75962708e-01, 6.62795103e-01, 6.16208160e-01, - 1.13864251e-01, 2.53682004e-01, 6.23642088e-01, 8.98394418e-01, - 6.43753008e-01, 7.31750809e-01, 1.56984479e-01, 4.40223144e-01, - 2.28920095e-01, 1.26804167e-01, 2.20281989e-01, 1.98547324e-01, - 3.20564984e-01, 2.21365943e-02, 2.21559477e-01, 7.42704049e-01, - 3.85612736e-01, 3.14809258e-01, 7.86060555e-01, 5.11447151e-01, - 8.41784475e-01, 5.59739247e-02, 1.62071758e-01, 8.69973637e-01, - 7.40171035e-01, 3.56223266e-01, 4.51027937e-01, 7.18955818e-01, - 5.55427487e-01, 1.39307159e-01, 2.03444834e-01, 5.67147572e-01, - 5.57513418e-01, 6.68842995e-01, 6.34503555e-01, 8.51115981e-01, - 1.30121768e-01, 4.39452406e-01, 6.51566025e-01, 4.30033735e-02, - 4.53622277e-01, 4.00969361e-01, 3.35681361e-01, 1.91029700e-01, - 8.94004702e-01, 4.72818707e-01, 6.43628049e-01, 7.74350225e-01, - 1.16116751e-01, 4.03800048e-01, 1.65561265e-01, 3.90710462e-02, - 3.11661710e-01, 1.53820919e-01, 9.71715921e-01, 6.66384485e-01, - 9.72690165e-01, 2.61938693e-01, 8.29244113e-01, 5.87743977e-03, - 3.47437760e-01, 2.81038913e-01, 9.43336660e-01, 4.22115291e-01, - 5.51480637e-02, 8.37854573e-01, 1.57179652e-02, 7.93045574e-02, - 5.57851326e-01, 6.96702009e-01, 2.86106747e-01, 8.23801131e-01, - 3.63651770e-01, 1.37242347e-02, 4.48045206e-01, 3.52525589e-01, - 7.69569691e-01, 6.86002139e-01, 7.69509966e-01, 3.44147593e-01, - 1.81635039e-01, 5.63247242e-01, 5.59495601e-01, 2.25528428e-01, - 5.17906955e-01, 5.39830628e-01, 9.77978851e-01, 1.28756923e-01, - 6.21543235e-01, 7.60604574e-01, 7.12956305e-01, 3.28861045e-01, - 6.07457612e-01, 8.17584800e-01, 2.58073899e-01, 2.71478889e-01, - 6.90569169e-01, 3.04929366e-01, 3.21495094e-01, 9.31576852e-01, - 7.76784069e-01, 4.83600053e-01, 6.60327979e-02, 2.36839578e-01, - 6.47323092e-01, 3.38791142e-01, 2.25976904e-01, 4.60322008e-01, - 7.91324886e-02, 5.68111985e-02, 9.68530371e-01, 9.03778030e-01, - 6.72483063e-01, 5.36745941e-01, 2.70638711e-01, 6.34570643e-01, - 6.24602692e-01, 1.16697301e-01, 2.64656305e-01, 2.36728403e-01, - 9.35274164e-01, 7.38961910e-02, 7.53428548e-02, 6.98464754e-01, - 6.04746161e-02, 5.85141483e-01, 5.49635035e-01, 3.59332528e-01, - 1.32046694e-01, 5.87671170e-01, 4.95754754e-01, 8.95385235e-01, - 3.13310068e-01, 1.06790548e-01, 5.88620743e-01, 8.57553634e-01, - 9.98100562e-01, 4.38280375e-01, 2.09730992e-01, 6.93059723e-01, - 6.32903971e-01, 5.17114267e-01, 8.73673332e-02, 2.39260365e-01, - 9.50826048e-01, 7.09171327e-01, 9.13340881e-01, 7.31244958e-01, - 5.58105885e-01, 7.63020105e-01, 1.80168672e-01, 6.64540527e-01, - 4.40438267e-01, 6.86114371e-01, 7.28113485e-01, 9.31472446e-01, - 4.70326358e-01, 3.89769582e-01, 4.53731736e-01, 1.90862675e-01, - 7.88358001e-01, 9.03167120e-01, 2.89049311e-02, 8.19188726e-01, - 1.00671977e-01, 6.48859926e-01, 7.66033464e-01, 4.90798051e-01, - 2.92120329e-02, 8.85040531e-01, 9.50276272e-01, 6.59853538e-01, - 6.87781041e-01, 4.72308452e-01, 3.48310805e-01, 5.16752029e-01, - 3.30939823e-01, 9.34661495e-01, 8.84183554e-01, 5.64139545e-01, - 3.71589673e-02, 7.90825320e-01, 3.24254340e-02, 1.03112129e-01, - 6.24809200e-01, 6.61016549e-01, 8.30842454e-01, 6.48075177e-01, - 1.63824068e-01, 1.80501894e-01, 2.69806743e-02, 7.97901562e-01, - 8.73214578e-01, 8.23781455e-02, 4.41077184e-01, 8.14281744e-01, - 8.38220372e-01, 7.11401445e-01, 9.98388075e-02, 8.32266347e-01, - 7.50407546e-01, 5.18934011e-01, 2.36028627e-02, 7.23147252e-01, - 1.09822401e-01, 5.41577941e-01, 7.07603390e-01, 8.38653795e-01, - 8.72934973e-01, 1.61208532e-01, 4.37979942e-02, 8.05917472e-01, - 1.70862226e-01, 6.68061745e-01, 7.23535495e-01, 6.55255428e-01, - 3.79277224e-01, 2.42366650e-01, 3.11588703e-01, 9.54839971e-01, - 7.19243773e-01, 3.11043858e-01, 5.73941494e-01, 8.50660378e-01, - 9.54982580e-03, 8.61089449e-01, 9.25997967e-01, 7.18995698e-01, - 8.48294256e-01, 4.62163126e-01, 8.28878010e-01, 9.40533542e-01, - 4.12123917e-01, 6.52866417e-02, 8.48171677e-01, 1.66818093e-01, - 7.22151560e-01, 4.09911346e-01, 9.40170702e-01, 8.40881727e-01, - 3.15975146e-01, 9.04856631e-01, 8.61597915e-01, 2.98573826e-01, - 2.93275893e-01, 7.39686037e-01, 9.16749149e-01, 8.64959196e-01, - 1.14782190e-01, 6.25620140e-01, 9.66841982e-01, 2.45214207e-01, - 1.82117343e-01, 6.78560130e-02, 9.13602911e-01, 3.18439999e-01, - 1.17489861e-01, 8.37738634e-01, 6.88803817e-01, 3.72079384e-01, - 9.81933370e-01, 6.25610523e-01, 6.34913442e-01, 6.37501490e-01, - 9.55689526e-01, 1.04286618e-01, 6.23448846e-01, 9.30493165e-02, - 7.08930185e-01, 5.97449025e-01, 3.21924112e-01, 2.07761517e-01, - 3.00325347e-01, 6.69578674e-01, 5.29394366e-01, 9.24879076e-01, - 7.11409192e-01, 1.77027117e-01, 9.06776058e-01, 2.26962776e-01, - 2.05829972e-01, 5.94427570e-01, 5.09323369e-01, 9.18138337e-01, - 7.80423501e-01, 6.78083818e-01, 9.53799881e-01, 6.99541127e-01, - 7.75430765e-01, 7.08234647e-01, 1.18675152e-01, 9.76904826e-01, - 2.51768126e-01, 5.86829970e-01, 7.20266785e-01, 6.61479327e-01, - 1.76079575e-01, 3.39683818e-01, 8.97698030e-01, 7.22314888e-01, - 3.29057090e-01, 9.73537738e-01, 7.69182537e-01, 7.25195101e-01, - 5.39294909e-01, 9.14759990e-01, 7.05701592e-01, 3.64908013e-02, - 1.64869704e-01, 1.65961009e-02, 3.32424967e-02, 5.47289496e-01, - 5.70394494e-01, 8.03394182e-01, 8.37832155e-01, 8.93858503e-01, - 3.70406151e-01, 9.71684676e-01, 9.84638158e-01, 8.16090310e-01, - 3.52964409e-01, 2.26780945e-01, 5.34103288e-01, 7.57007027e-01, - 2.48122510e-01, 6.52326815e-01, 3.63498094e-01, 7.32110131e-01, - 9.17774053e-01, 8.88846797e-01, 6.86428183e-01, 7.32652603e-01, - 5.95586080e-01, 8.39563793e-01, 8.26122318e-01, 3.66732098e-01, - 8.25373209e-01, 2.80269431e-01, 1.38494853e-01, 2.70283618e-01, - 7.92609090e-01, 7.95120398e-01, 5.86164837e-01, 2.32304473e-01, - 4.23520411e-01, 6.00331206e-01, 9.47899638e-01, 7.83849206e-01, - 9.09825293e-02, 1.48691470e-01, 4.31205796e-01, 2.86079763e-01, - 9.05188382e-01, 3.12373838e-01, 8.81830708e-01, 1.13861123e-01, - 4.33651514e-01, 7.76116989e-03, 6.54689548e-01, 8.95913326e-02, - 2.00499612e-01, 6.24586410e-01, 7.49943935e-01, 2.17308870e-01, - 8.81175198e-01, 9.51923552e-01, 8.28504768e-01, 3.36433124e-01, - 1.26263169e-01, 3.70242060e-01, 8.29145642e-01, 6.20793064e-01, - 6.30890711e-02, 4.74349619e-03, 4.94081018e-01, 3.44532663e-01, - 6.96904582e-02, 2.90926003e-01, 6.06143663e-01, 7.47535614e-01, - 3.42266526e-01, 4.67872881e-01, 4.81118884e-01, 7.41796303e-01, - 7.46412947e-02, 1.52662173e-02, 9.70259944e-01, 7.86156229e-01, - 5.81743012e-01, 3.03130443e-01, 6.46081571e-02, 3.14974196e-01, - 6.93277960e-01, 8.32261271e-02, 6.96308407e-01, 6.40907926e-01, - 2.45965091e-01, 7.09653017e-01, 2.28339380e-01, 1.21844492e-01, - 6.78876752e-01, 2.02368003e-01, 7.93857283e-01, 7.95545403e-02, - 6.62529991e-01, 4.14764518e-01, 9.65061340e-01, 4.64787127e-01, - 8.00736722e-01, 4.58155481e-01, 7.97360280e-01, 5.03906327e-01, - 3.70894338e-01, 7.62966412e-01, 3.41887723e-02, 3.28877376e-01, - 9.48152230e-01, 6.14377987e-01, 8.31598857e-01, 4.02787771e-01, - 7.89170122e-01, 6.16831973e-01, 8.82136733e-01, 6.51538121e-01, - 3.40828301e-03, 1.32384245e-01, 3.40397288e-01, 6.47307330e-01, - 3.20716817e-01, 6.91273248e-01, 5.41961787e-01, 4.89032995e-01, - 7.71502962e-01, 5.70432391e-01, 7.59325490e-01, 8.48202327e-01, - 3.04159605e-01, 4.48849226e-01, 1.67951797e-01, 2.27212712e-01, - 6.83528832e-01, 7.25063393e-01, 9.93452424e-01, 2.62273404e-01, - 4.93810104e-01, 5.23750223e-01, 1.91858569e-01, 4.35240695e-02, - 1.97876990e-01, 3.29177471e-01, 3.04972488e-04, 8.33490954e-01, - 5.23238694e-01, 4.46638340e-01, 2.71284859e-01, 4.19057103e-01, - 1.21724201e-01, 8.27791414e-01, 7.21628294e-01, 9.19986812e-01, - 9.35140750e-01, 3.75794944e-01, 9.56673021e-01, 6.49316296e-01, - 8.52679545e-01, 4.52986925e-01, 8.65245637e-01, 3.61151812e-01, - 8.83369213e-01, 6.23015849e-01, 8.80019975e-01, 9.71597400e-01, - 8.03321907e-01, 4.58589982e-01, 9.70689575e-01, 5.88408087e-01, - 2.67446801e-02, 2.26081080e-01, 3.72502710e-01, 5.18017729e-01, - 6.97848301e-01, 1.11533833e-02, 1.15989123e-01, 5.73253222e-02, - 6.15797763e-01, 4.36061694e-01, 1.32861084e-01, 6.51307912e-01, - 9.65943445e-01, 9.46475591e-01, 9.44260602e-01, 2.94840118e-01, - 1.88560924e-01, 6.77128258e-01, 9.52484675e-01, 1.33865981e-01, - 8.54146793e-01, 8.90577957e-02, 2.11491058e-01, 9.35210260e-02, - 5.26777010e-01, 6.56970772e-01, 5.85237862e-01, 1.75293799e-01, - 2.38045167e-01, 7.04148978e-02, 9.06796119e-01, 6.59266858e-01, - 1.80639432e-01, 7.95717345e-01, 4.56240189e-01, 3.81653268e-01, - 6.05633362e-01, 8.32495907e-01, 1.59136315e-01, 7.95481552e-01, - 9.46817864e-01, 9.47791652e-01, 5.05922343e-01, 6.77495961e-01, - 9.78010337e-01, 1.37835768e-01, 6.82173898e-01, 3.29347815e-01, - 9.50828687e-01, 7.23507361e-02, 2.09540106e-02, 5.61469640e-01, - 2.69103741e-01, 4.50867628e-01, 9.68220376e-01, 9.00338277e-01, - 1.11610400e-01, 5.38335967e-01, 1.74701649e-01, 8.64694365e-01, - 1.89753336e-01, 7.95222604e-02, 3.01202421e-02, 3.13545816e-01, - 8.06559078e-01, 6.38338768e-02, 7.46182571e-01, 6.25119320e-01, - 5.41727273e-01, 6.76925185e-01, 9.60211713e-01, 2.65303850e-01, - 8.71288685e-02, 9.87959272e-01, 2.33741328e-01, 3.43865754e-01, - 6.87328898e-01, 5.08280716e-01, 6.44323047e-01, 2.12316663e-01, - 6.95363966e-01, 7.43354605e-01, 9.86640432e-01, 1.93662218e-01, - 4.51918040e-01, 6.98536368e-01, 4.27234418e-01, 3.18267987e-01, - 7.23525475e-01, 6.37590551e-01, 7.56891147e-01, 1.12875351e-01, - 5.43071437e-01, 5.67604800e-01, 8.69433810e-01, 4.22249989e-01, - 9.21198255e-02, 3.54702740e-01, 6.84999683e-01, 8.16958028e-01, - 4.06961846e-01, 1.18200063e-01, 1.23469628e-01, 7.21167252e-01, - 2.71046415e-01, 3.36668549e-01, 3.97949914e-01, 7.42482378e-01, - 7.47981401e-01, 7.78112282e-01, 7.30924456e-01, 6.59854796e-01, - 1.03592459e-01, 6.75703864e-01, 5.70338460e-01, 6.79150944e-01, - 6.69903770e-01, 3.82185660e-01, 8.31238061e-01, 2.59920340e-01, - 4.30541218e-01, 1.81508574e-01, 8.12640025e-03, 4.77909754e-01, - 9.53608622e-01, 2.97678037e-01, 2.74910037e-01, 2.02071748e-01, - 8.30354579e-01, 3.53941366e-01, 6.98485636e-01, 9.48972263e-01, - 1.02703365e-01, 3.31339850e-01, 7.91926857e-01, 5.86240067e-02, - 5.15643169e-01, 2.33328945e-01, 5.11936388e-01, 3.01053825e-01, - 9.32559125e-01, 5.52791125e-01, 5.56256708e-02, 2.33923262e-02, - 4.20381337e-01, 9.33832824e-01, 2.53670976e-01, 9.69247613e-02, - 7.36729781e-01, 6.31738973e-02, 9.71696339e-01, 8.01241562e-01, - 3.09146300e-01, 6.85179246e-01, 5.74895308e-01, 3.33924642e-01, - 8.68068076e-01, 2.39791146e-01, 8.04124546e-01, 2.45866254e-01, - 8.72816537e-01, 2.56117437e-01, 7.59241929e-01, 1.75999550e-01, - 7.17279236e-01, 1.03176836e-01, 4.40717391e-01, 4.27309182e-01, - 8.69288331e-01, 6.96183932e-01, 3.01024762e-01, 3.57350611e-01, - 5.52794409e-01, 4.93132601e-01, 5.09546441e-01, 6.84150057e-01, - 3.79250310e-01, 3.76902888e-01, 5.98274291e-01, 8.05906253e-01, - 3.77474176e-01, 9.00157802e-01, 6.66988939e-01, 5.23412136e-01, - 2.86820270e-01, 7.81255742e-01, 8.56514003e-01, 2.37522131e-01, - 1.79874039e-01, 1.42103574e-01, 5.27416220e-01, 7.55706133e-01, - 9.43644544e-01, 1.14794332e-01, 9.17943949e-01, 1.71947052e-01, - 1.03421052e-01, 7.09183034e-01, 6.24529802e-01, 9.91979882e-01, - 4.57969737e-01, 1.06292360e-01, 7.54458210e-01, 6.89607757e-01, - 4.57445849e-01, 6.95306056e-01, 5.43155295e-01, 9.71219157e-01, - 4.61575550e-01, 5.34795171e-01, 8.58721491e-01, 8.92932864e-01, - 1.37488682e-01, 4.03353217e-01, 9.61973999e-02, 2.38900357e-01, - 2.23009993e-01, 4.81163975e-01, 3.18089770e-01, 8.46441974e-01, - 7.61390313e-01, 6.98668535e-01, 9.87180329e-01, 5.43150576e-01, - 5.07675090e-01, 2.42547762e-01, 4.04915929e-01, 7.89859765e-01, - 8.49283774e-01, 6.82575084e-01, 1.75624000e-01, 9.62116402e-01, - 3.54642938e-01, 7.93029168e-01, 6.81483532e-01, 5.82446618e-01, - 3.93532636e-01, 2.32569365e-02, 9.46114319e-01, 5.68364396e-01, - 3.50999775e-01, 4.79305230e-02, 2.88544377e-01, 7.28636898e-01, - 3.11413710e-01, 8.79198378e-01, 8.67337001e-01, 7.99535425e-01, - 2.91198110e-01, 3.01695765e-01, 9.76821106e-01, 5.88110424e-01, - 5.90613357e-01, 7.69730486e-01, 2.83473394e-01, 8.26827146e-01, - 3.16196255e-03, 3.37972141e-01, 9.88618803e-01, 1.39080547e-01, - 7.83144068e-01, 2.88921721e-01, 1.28304874e-02, 6.75349250e-01, - 6.83286179e-01, 4.99916919e-01, 4.97452670e-01, 4.56819263e-01, - 6.79448493e-01, 8.97614699e-01, 2.66447909e-01, 7.86028565e-01, - 7.96762987e-01, 8.85525380e-01, 6.42010678e-01, 6.89314660e-01, - 5.60529219e-01, 3.50510208e-01, 3.54991078e-01, 7.30942246e-01, - 4.90206771e-01, 5.03675702e-01, 4.20625068e-02, 1.60267939e-01, - 3.93979561e-01, 7.98968322e-01, 3.16348656e-01, 2.01832693e-01, - 2.46196473e-01, 9.12775114e-01, 2.05830514e-01, 6.70622277e-01, - 9.55204724e-01, 8.53499621e-01, 4.05659342e-01, 6.42852505e-01, - 7.10368404e-01, 9.85672826e-01, 5.22335610e-01, 6.17257427e-01, - 2.10168749e-01, 3.91883977e-02, 6.23935924e-01, 3.08249153e-01, - 1.48043820e-01, 4.29017962e-01, 3.81915495e-01, 6.64484076e-01, - 5.95697760e-02, 4.49421742e-01, 7.60924114e-02, 2.97092620e-01, - 3.69015418e-01, 1.99398822e-01, 7.13120938e-01, 4.90608942e-01, - 2.55956050e-01, 1.15931804e-01, 2.65739230e-01, 6.95050602e-02, - 2.28148923e-01, 2.53978205e-01, 7.48474937e-01, 4.64114984e-01, - 6.11688110e-01, 1.64176681e-02, 4.28609047e-01, 7.55192971e-01, - 1.91176457e-01, 2.37300686e-01, 5.82715387e-01, 3.26180071e-01, - 4.41388668e-02, 1.50616879e-01, 5.40684117e-01, 1.98670940e-01, - 3.90193589e-01, 2.00872943e-01, 3.96390382e-02, 2.01952262e-01, - 8.65773997e-02, 7.78135413e-01, 5.66935157e-01, 8.54323130e-01, - 6.34795405e-02, 3.02726192e-01, 4.71595156e-01, 9.05002519e-01, - 9.49341119e-01, 4.43354491e-01, 1.74919522e-01, 3.96306576e-01, - 2.34611668e-02, 3.41141240e-01, 6.88332437e-01, 5.93704034e-01, - 9.10742757e-01, 2.47513034e-01, 1.30009404e-01, 4.79380595e-01, - 4.12512105e-01, 5.27279416e-01, 1.21502829e-01, 8.62005619e-01, - 3.94882866e-01, 1.46732491e-02, 7.01567612e-02, 2.26620965e-01, - 3.95324049e-01, 4.41922144e-01, 9.26418841e-01, 1.72320921e-01, - 3.82164306e-01, 7.81638763e-01, 9.18169559e-01, 2.60941703e-01, - 3.41689158e-01, 9.17607008e-01, 8.49148931e-01, 8.74908102e-02, - 1.78918873e-01, 6.41279534e-01, 5.01119448e-01, 1.74456896e-01, - 6.08854366e-01, 5.86400285e-01, 3.74814704e-01, 7.13765690e-02, - 7.94730717e-01, 8.62809856e-01, 3.53704151e-01, 2.34038496e-01, - 4.14507914e-02, 7.05298973e-01, 7.74714979e-01, 5.99646169e-01, - 5.63215482e-01, 2.14126063e-03, 9.48156758e-01, 6.62962461e-01, - 4.76069654e-01, 9.82189519e-01, 6.09958227e-01, 6.26967132e-03, - 3.48775981e-01, 5.22081206e-01, 3.83073392e-01, 7.34956665e-02, - 3.88333573e-01, 1.60664035e-01, 5.09877065e-01, 5.52157733e-01, - 4.31655760e-01, 4.60277098e-01, 3.71647195e-01, 8.07950553e-01, - 3.51371306e-02, 3.47044301e-01, 6.91446218e-01, 7.32118785e-01, - 1.36860717e-01, 6.90275046e-03, 3.29235453e-01, 7.51278882e-01, - 4.30870775e-01, 2.36302227e-01, 3.70297792e-01, 5.99070044e-01, - 1.42759639e-01, 7.51552579e-01, 8.01303595e-01, 6.96139313e-01, - 6.47544758e-01, 7.91415262e-01, 9.08546686e-01, 5.56580572e-01, - 5.43777442e-01, 1.25130376e-01, 4.99283047e-01, 4.75479041e-02, - 7.16442389e-01, 9.16798249e-01, 2.90504379e-01, 7.70952913e-01, - 7.08851028e-01, 9.28349783e-01, 6.99956039e-01, 8.89243871e-01, - 7.12117654e-01, 4.70064596e-01, 7.23101431e-01, 6.02579469e-01, - 2.70879869e-01, 7.55669789e-01, 2.37187622e-01, 9.99421496e-01, - 2.17781018e-01, 3.03285437e-02, 9.69635771e-01, 1.70569973e-01, - 8.71286711e-01, 9.27828077e-03, 6.53005352e-01, 3.53159788e-01, - 9.78424850e-01, 3.99576178e-02, 1.60529919e-01, 1.13074361e-01, - 6.33820624e-01, 5.31506945e-01, 4.64256293e-01, 9.58932714e-01, - 7.39209641e-01, 8.50208553e-01, 8.17003515e-01, 2.33737166e-01, - 5.18528745e-01, 3.01821746e-01, 1.76899400e-01, 1.32706376e-01, - 9.54769058e-01, 6.33002388e-01, 2.04246835e-01, 1.72337354e-01, - 4.19794547e-01, 5.05213293e-02, 7.02624190e-01, 1.77560384e-01, - 6.91976575e-01, 5.58037859e-01, 7.57545014e-01, 5.52119118e-01, - 4.50284697e-01, 1.54567048e-01, 2.35593591e-01, 7.93746045e-01, - 5.59623343e-01, 6.56726677e-01, 6.18540185e-02, 5.32813342e-01, - 9.28778636e-01, 1.82237287e-02, 6.94747455e-01, 5.53451075e-01, - 1.17457578e-01, 8.41959465e-02, 4.30655855e-01, 3.18721330e-02, - 8.85510860e-01, 4.07483338e-01, 3.82438196e-01, 9.67492837e-01, - 4.83333659e-01, 3.48289304e-02, 3.28717749e-01, 9.27005757e-01, - 1.86092641e-01, 1.93651424e-01, 7.78158750e-01, 3.43323412e-01, - 8.77499307e-01, 9.13954107e-01, 8.10678527e-03, 5.90758463e-01, - 8.40488738e-01, 3.70162725e-01, 6.49109620e-01, 5.58430028e-01, - 4.88604483e-01, 9.06265106e-01, 6.02380040e-01, 6.90543512e-01, - 3.19062117e-01, 8.15405368e-01, 5.50682479e-01, 6.40259343e-01, - 8.70575420e-01, 5.38149570e-01, 4.21968363e-01, 5.47452828e-01, - 6.16975975e-01, 5.50823415e-01, 8.55618928e-01, 8.22240534e-01, - 3.99101284e-01, 4.90405471e-01, 2.19010106e-01, 1.85975691e-01, - 2.57120897e-01, 2.12485292e-01, 9.93864220e-01, 9.69260739e-01, - 6.93063256e-01, 1.03269401e-01, 9.77334048e-01, 7.53686820e-01, - 1.16905301e-01, 6.00001000e-01, 7.35255088e-01, 4.64102602e-02, - 3.53820642e-01, 2.50878091e-01, 2.37320793e-01, 7.18205684e-01, - 5.23954402e-01, 1.02606800e-01, 3.52420052e-01, 9.15295828e-01, - 8.03228185e-01, 1.88864574e-01, 4.64225071e-02, 2.85621607e-01}; -} } /* namespaces */ +static const double values[] = { + 5.36812441e-01, 9.05016283e-01, 2.21117887e-01, 5.02819496e-01, + 7.63086501e-01, 6.53893270e-01, 8.23665727e-01, 9.69872102e-01, + 3.40061134e-01, 1.51051652e-01, 1.90729935e-01, 3.95479722e-01, + 8.75884366e-01, 7.05225909e-01, 9.67985410e-01, 9.67231568e-01, + 3.16638187e-01, 2.07409147e-01, 8.73259933e-01, 6.43942066e-01, + 1.78484038e-02, 7.12456953e-01, 8.86710346e-01, 9.38996311e-01, + 3.35287423e-01, 8.90043645e-01, 9.34030467e-01, 5.15824085e-01, + 6.23115364e-02, 1.16789345e-01, 8.50941823e-01, 1.67876163e-01, + 1.31041168e-01, 9.93168994e-02, 1.41431817e-01, 8.90690809e-01, + 2.02488098e-01, 7.36300956e-01, 1.55234556e-02, 2.20287030e-01, + 9.36321073e-01, 1.28409939e-01, 3.08036214e-01, 8.67956164e-02, + 1.11136507e-01, 9.60890548e-01, 9.88958063e-01, 9.53397532e-01, + 5.79151680e-01, 7.23213235e-01, 2.27149695e-01, 7.58832055e-01, + 1.12813268e-01, 8.35874616e-01, 1.89134687e-01, 5.12455825e-01, + 4.25818943e-02, 3.11057974e-01, 5.20592461e-01, 4.14944838e-01, + 7.62577185e-01, 8.77537698e-02, 3.77975887e-01, 1.07129081e-01, + 2.80648306e-01, 1.57044211e-01, 9.24362351e-01, 9.60771393e-01, + 2.30143289e-01, 9.80732668e-01, 4.22272940e-01, 2.44685865e-01, + 9.95728448e-01, 7.03337832e-01, 9.43639937e-01, 4.10483955e-01, + 5.49454891e-01, 2.73267928e-02, 7.54862939e-01, 4.10246593e-02, + 6.72925227e-01, 8.45630228e-01, 8.24185778e-01, 5.86034357e-01, + 2.45186711e-01, 1.46556640e-02, 7.83866884e-01, 3.27409940e-01, + 1.87732538e-01, 3.08269456e-01, 9.41082410e-01, 8.60992214e-01, + 4.29335830e-01, 7.30630195e-01, 2.26017436e-01, 5.64492936e-01, + 7.53212812e-02, 5.46318587e-01, 2.06760814e-01, 8.63181719e-01, + 5.14394315e-01, 6.09138749e-01, 4.18657254e-01, 5.91929447e-01, + 8.92082831e-01, 2.19417367e-01, 4.77365478e-02, 7.26974646e-01, + 3.90718957e-01, 5.60553601e-01, 8.68079340e-01, 6.66149233e-01, + 5.65605279e-01, 4.17322107e-01, 3.58916838e-02, 3.20056919e-01, + 4.69409876e-01, 4.59560328e-01, 3.78865664e-01, 4.70873097e-01, + 6.33834299e-01, 3.56360349e-02, 4.72834116e-01, 5.98245954e-01, + 6.71737750e-01, 3.24785236e-01, 4.72058687e-01, 8.73592505e-01, + 8.17040665e-01, 5.24633123e-01, 1.19966059e-01, 3.31976138e-01, + 9.46976980e-01, 9.33750854e-01, 4.55336961e-01, 3.99956066e-03, + 4.60555081e-01, 2.75436730e-02, 4.45222636e-01, 3.81840487e-01, + 6.90430349e-01, 4.69071563e-01, 8.79427375e-02, 5.51342939e-01, + 5.59734456e-02, 2.75721390e-01, 7.01775098e-01, 1.85279466e-01, + 7.87023428e-01, 8.65878578e-01, 3.46338346e-01, 1.98827346e-01, + 4.62406412e-01, 9.36147813e-01, 6.73068785e-01, 8.21165652e-01, + 3.84137201e-01, 5.54849070e-01, 5.25338471e-01, 4.92960187e-01, + 1.98987654e-01, 4.40366612e-01, 4.91615585e-01, 6.59636951e-01, + 6.56862278e-01, 9.91108369e-01, 2.64080613e-02, 1.59392509e-01, + 1.59326848e-01, 9.80768641e-01, 7.23541978e-01, 6.24664106e-02, + 5.23245400e-01, 8.29540568e-01, 3.79595827e-01, 2.51490705e-01, + 9.03211923e-01, 5.85036337e-01, 2.13804243e-02, 7.02601545e-01, + 8.84451972e-01, 7.44386759e-01, 4.07704650e-01, 8.76135540e-01, + 8.62283593e-02, 8.12646966e-01, 1.99860200e-03, 9.81822688e-01, + 3.98059813e-01, 7.07509226e-01, 3.29087549e-01, 1.49488172e-01, + 9.28632230e-01, 8.67940978e-01, 7.57588079e-01, 2.41147841e-02, + 1.16906710e-01, 9.01610642e-01, 6.48063108e-01, 1.38901827e-01, + 3.69400192e-01, 1.70098717e-02, 6.86210800e-01, 5.19651542e-01, + 9.95125346e-01, 8.59978505e-01, 7.77940487e-01, 7.00603844e-01, + 7.64288441e-01, 7.71847112e-01, 7.68801253e-01, 5.62508922e-01, + 2.78507048e-01, 9.00805306e-02, 5.41263065e-01, 3.91795734e-01, + 7.01280661e-01, 8.76551939e-01, 2.44363950e-01, 7.91509644e-01, + 6.90857642e-01, 7.63697059e-01, 6.45428558e-01, 6.82167839e-01, + 8.33239992e-01, 7.63494477e-01, 9.41177879e-01, 2.56919197e-02, + 1.95005612e-01, 2.17610152e-01, 4.10317359e-01, 7.49023537e-01, + 8.67374419e-02, 8.33918551e-01, 2.89078914e-01, 5.54389435e-01, + 7.79647807e-01, 2.67859885e-01, 3.22589228e-01, 5.73316233e-01, + 2.52832617e-01, 8.35869300e-01, 3.30812610e-01, 9.55867629e-01, + 2.28908323e-01, 9.93198329e-01, 3.98123397e-01, 8.99333947e-01, + 3.82249010e-01, 7.97028510e-01, 7.05980223e-01, 7.93472013e-01, + 8.15960458e-01, 7.50921468e-01, 6.87093503e-01, 6.84088372e-01, + 6.92497398e-01, 3.96633688e-01, 4.13013887e-01, 2.28475282e-01, + 4.60155416e-01, 3.46243470e-01, 7.20709879e-01, 2.94614335e-01, + 6.62684881e-01, 1.36982656e-02, 3.82961800e-01, 8.04081364e-01, + 5.40473423e-01, 3.14540500e-01, 6.23210130e-01, 6.82965861e-01, + 6.31577863e-01, 1.84412937e-01, 8.04611334e-01, 2.25748741e-01, + 9.47193866e-01, 7.36543339e-01, 2.56602607e-02, 8.51909736e-02, + 9.88778351e-01, 1.49808112e-01, 3.91534041e-01, 9.13229877e-01, + 1.81587719e-01, 7.99617499e-01, 4.48458315e-01, 8.57410766e-01, + 7.84580475e-01, 2.68411587e-01, 6.90255704e-01, 1.04220834e-01, + 8.35958260e-01, 6.58782564e-01, 4.78765310e-01, 7.81194957e-01, + 5.99885434e-01, 8.09630883e-01, 1.04707323e-01, 4.72111341e-01, + 9.41931033e-01, 5.04752488e-01, 5.78791731e-01, 2.97554626e-01, + 4.01089318e-01, 2.49185489e-01, 3.85964501e-01, 6.60440483e-01, + 7.73563635e-02, 5.97169647e-01, 7.50404109e-01, 8.85433745e-01, + 1.18036176e-01, 3.36861628e-01, 9.16758521e-01, 4.10648405e-01, + 6.55235522e-01, 3.34384242e-01, 3.88493234e-01, 4.20717897e-01, + 5.28649522e-02, 7.60592922e-01, 6.17367275e-01, 2.34571785e-01, + 5.15619540e-01, 5.81380856e-01, 6.70578777e-01, 4.31113333e-01, + 1.56436542e-01, 6.98107974e-01, 2.76652979e-01, 6.97987014e-01, + 2.98738915e-01, 8.22720683e-01, 9.24549465e-02, 3.78968100e-01, + 1.28890640e-01, 4.12131016e-04, 9.34899694e-01, 9.73355458e-01, + 7.60564472e-01, 9.02434830e-01, 3.75690070e-01, 9.52636429e-01, + 2.91106624e-01, 4.23821343e-01, 1.30204911e-01, 2.72353454e-01, + 2.41791015e-01, 6.55615660e-01, 2.62696179e-01, 9.45745111e-01, + 7.95702851e-01, 6.93790316e-01, 5.57819907e-01, 3.19620135e-01, + 9.11573270e-01, 5.27465702e-01, 9.51558175e-01, 2.95387619e-01, + 6.84395148e-01, 8.49952813e-01, 3.26668856e-01, 9.78348880e-01, + 9.19534607e-02, 2.42212135e-01, 5.32824662e-01, 7.17067053e-02, + 4.71115746e-01, 7.70158064e-01, 8.47999498e-01, 4.20158937e-01, + 4.55412652e-01, 7.19081870e-01, 1.38691180e-01, 8.68676168e-02, + 1.51498147e-02, 5.68162660e-01, 8.72790465e-02, 1.31312082e-01, + 9.79495283e-01, 6.75099064e-01, 2.24999849e-01, 9.76569106e-01, + 7.67219663e-01, 4.37956888e-01, 1.65439333e-01, 9.41914179e-01, + 6.65583742e-01, 9.27526495e-01, 2.37504549e-01, 6.20414894e-01, + 7.77084421e-01, 5.58427639e-01, 1.94030841e-01, 9.61331000e-01, + 9.04209376e-01, 9.63892747e-01, 9.46209175e-01, 9.04518643e-01, + 7.26399734e-01, 9.83897979e-01, 8.27304272e-01, 3.32530991e-01, + 9.84515497e-01, 2.56890432e-01, 4.13745647e-02, 6.15384113e-02, + 1.01896215e-02, 9.91252119e-01, 7.41949546e-02, 5.08643664e-02, + 9.19594180e-01, 6.56879477e-01, 1.38321566e-01, 8.91272269e-01, + 3.76529356e-01, 1.43275785e-01, 8.49632410e-02, 4.14695708e-01, + 1.09868138e-01, 2.71223046e-01, 8.37391371e-01, 1.75748878e-01, + 7.46450754e-01, 2.62086328e-01, 3.02968832e-01, 3.08811921e-01, + 6.75112571e-01, 1.54663865e-01, 7.68687843e-02, 8.77842966e-01, + 5.95682123e-01, 8.84030026e-01, 4.11628111e-01, 1.39221484e-02, + 5.40001953e-01, 4.75558489e-01, 9.87355965e-01, 7.80989133e-01, + 9.13962355e-01, 2.22696195e-01, 5.78395818e-01, 8.08965138e-01, + 6.06214278e-01, 7.89805419e-01, 6.39241167e-01, 9.12456228e-01, + 1.67840880e-01, 3.53944938e-01, 4.39652426e-01, 9.72728897e-01, + 5.09008884e-01, 4.06519841e-01, 9.05467696e-01, 3.61380329e-01, + 8.36748412e-01, 8.27654293e-01, 3.69483653e-01, 2.35592710e-01, + 4.43410231e-01, 8.45589729e-02, 2.65186217e-01, 9.00911601e-01, + 8.37081370e-01, 9.94206284e-01, 6.27674149e-01, 2.83436085e-01, + 4.91578394e-01, 2.39388739e-01, 7.53775833e-01, 7.65900773e-01, + 7.15594596e-01, 6.91507628e-01, 8.68231103e-01, 8.27670658e-01, + 2.66069794e-02, 9.24833718e-01, 4.07264594e-01, 6.46532156e-01, + 3.05981566e-01, 6.72368241e-01, 9.48028447e-01, 7.57749971e-01, + 4.23917031e-01, 8.29638611e-01, 2.22636497e-02, 4.33986046e-01, + 2.89018838e-01, 7.81398654e-01, 3.39236836e-02, 2.46990497e-01, + 6.03205453e-01, 4.54589789e-01, 9.40588634e-01, 7.24938657e-01, + 3.25200097e-01, 1.35990964e-01, 6.30647885e-01, 2.49898974e-01, + 7.92871477e-01, 8.38301547e-01, 6.92965697e-01, 5.95539037e-03, + 6.93435428e-01, 1.17512906e-01, 1.07996451e-01, 6.80556483e-01, + 4.83315231e-01, 9.82720401e-01, 3.53397185e-01, 7.62348221e-01, + 8.62281735e-01, 7.43698891e-01, 5.63628921e-01, 4.61846055e-01, + 6.63495039e-01, 9.34262357e-01, 3.55006049e-02, 8.82918307e-02, + 9.63137670e-01, 5.25997210e-01, 7.84285486e-01, 1.57197155e-01, + 9.19628016e-01, 3.12345729e-01, 8.48558099e-01, 9.41241963e-01, + 8.04528060e-01, 1.86439955e-01, 8.55088666e-01, 6.05907190e-01, + 2.72833945e-01, 8.54406399e-02, 6.46909892e-01, 4.72546083e-02, + 6.74391082e-01, 3.70415944e-01, 8.16789315e-01, 8.12652539e-03, + 4.23180555e-01, 3.54543378e-01, 3.04230397e-01, 8.04708670e-01, + 6.91577567e-01, 2.96322435e-01, 4.61354184e-01, 5.93717371e-02, + 1.53499985e-01, 8.92148814e-01, 1.64638319e-01, 7.38604892e-01, + 6.02570691e-01, 5.34650510e-01, 6.68396934e-01, 8.02145367e-01, + 7.34817185e-01, 7.41494512e-01, 9.44356445e-01, 3.97851754e-01, + 8.03286601e-01, 7.80976959e-01, 6.49706333e-01, 5.25477011e-01, + 1.25350140e-01, 9.81939771e-01, 3.98778289e-01, 4.93460779e-01, + 8.29468443e-01, 3.66458821e-01, 2.18733806e-01, 3.66335915e-01, + 2.73011413e-01, 7.27958619e-01, 3.62424542e-01, 2.14509544e-01, + 4.13024987e-01, 4.72061154e-01, 5.53947740e-01, 5.31675692e-01, + 3.71925756e-01, 2.31208204e-01, 1.73726133e-01, 7.47059244e-01, + 6.83914622e-02, 1.77409894e-01, 5.17290543e-01, 1.70213457e-01, + 7.18947645e-01, 8.18895525e-01, 8.07188857e-01, 5.71988322e-02, + 3.47670155e-01, 4.16075155e-01, 9.26956424e-01, 2.32702268e-02, + 6.54650022e-01, 9.56034456e-01, 3.80220033e-02, 7.25930569e-01, + 9.85998591e-01, 8.77696544e-01, 6.53688575e-02, 3.71514876e-01, + 3.20639741e-01, 4.50013967e-01, 2.04994606e-01, 5.41234862e-01, + 8.28278185e-01, 8.40104449e-02, 7.62408153e-01, 9.74030597e-01, + 5.98201472e-01, 4.10348139e-01, 5.71331554e-01, 6.77575535e-01, + 5.00177981e-01, 7.83423781e-02, 3.78576641e-01, 9.11038480e-01, + 2.49289014e-01, 5.38592714e-02, 6.13534724e-01, 7.38466339e-01, + 7.27171126e-01, 4.74905476e-01, 9.40012900e-01, 4.44981968e-01, + 8.81997918e-01, 2.23525145e-01, 8.08694059e-01, 4.99111844e-01, + 6.79157051e-03, 2.19248046e-01, 9.13960278e-01, 5.24991491e-01, + 6.93940799e-01, 7.42648103e-01, 7.02214213e-01, 9.18667786e-01, + 7.59341472e-01, 3.54414552e-01, 9.46592781e-01, 5.20239076e-01, + 5.47405167e-01, 4.25788778e-01, 3.48108829e-01, 6.27264794e-01, + 8.95325979e-01, 9.33420332e-01, 3.82918759e-01, 5.54905966e-02, + 7.78169299e-01, 9.26901670e-01, 5.66105670e-01, 5.12692071e-01, + 5.34226058e-01, 8.66718175e-01, 7.84492694e-01, 1.68997042e-01, + 8.67033224e-02, 9.79202584e-01, 8.56753423e-01, 9.04184995e-01, + 5.00378023e-01, 7.46643152e-02, 3.29220649e-01, 4.98306376e-01, + 7.69615359e-01, 3.28224231e-01, 9.41188434e-01, 8.19528373e-01, + 5.93907766e-01, 5.98301237e-01, 3.85798398e-01, 6.75196282e-01, + 7.37105148e-01, 5.01794822e-01, 3.01794125e-01, 7.19154452e-01, + 6.40740024e-01, 6.12898801e-02, 5.37371628e-01, 3.27451153e-01, + 8.84910552e-01, 3.10629091e-01, 4.46631719e-01, 8.85742724e-01, + 6.83613510e-01, 2.07972972e-01, 4.93206267e-01, 3.74151928e-01, + 9.12954066e-01, 5.49843441e-01, 6.10165821e-01, 1.72061990e-01, + 8.99540060e-01, 5.06387833e-01, 2.52932211e-01, 3.80791581e-01, + 7.45111439e-01, 3.34417679e-01, 8.53005515e-01, 1.53964676e-02, + 7.80223373e-01, 8.03453467e-01, 5.40362876e-01, 5.60155057e-01, + 5.32810533e-01, 7.43661218e-01, 4.12663312e-01, 1.92132141e-01, + 6.16617146e-01, 4.86322891e-01, 9.37376605e-01, 5.52481104e-01, + 9.63440251e-01, 1.99438737e-01, 8.83420843e-01, 4.05579554e-02, + 1.34087876e-01, 5.26339200e-01, 7.48386928e-01, 5.94725741e-01, + 6.50249741e-01, 3.62297757e-01, 1.55316865e-01, 2.74679259e-01, + 2.51148216e-01, 5.05888061e-01, 7.50971491e-02, 8.60876909e-01, + 7.25551105e-01, 4.93888271e-01, 6.89908477e-01, 3.16459329e-01, + 7.02989702e-01, 9.46942980e-01, 7.07153678e-01, 9.41226034e-01, + 1.42636649e-01, 7.36429712e-01, 6.03964454e-01, 9.89378761e-01, + 6.18206628e-01, 9.91291847e-01, 8.66409471e-01, 2.45899762e-01, + 5.20574298e-01, 6.91097441e-01, 7.58355116e-01, 9.10371369e-01, + 6.85451953e-01, 5.39838611e-01, 4.94642157e-01, 2.72929998e-01, + 1.70949276e-01, 1.33503240e-01, 9.60196229e-01, 2.65671261e-01, + 9.49609345e-01, 3.60688343e-01, 5.24134421e-02, 7.11077155e-01, + 9.33813206e-01, 5.15476454e-01, 2.77628556e-01, 8.13224016e-01, + 1.42105292e-03, 7.86922642e-01, 1.56669917e-01, 4.65061482e-01, + 7.43575610e-01, 7.92485799e-01, 3.48647119e-01, 3.16826059e-01, + 5.89802524e-01, 7.39660055e-01, 3.13570895e-01, 8.99993136e-01, + 2.96715237e-01, 3.83340615e-01, 6.08502076e-01, 7.68345205e-01, + 1.60487380e-02, 7.79764476e-01, 1.00886185e-01, 5.94645519e-01, + 4.21534301e-01, 5.63961951e-01, 9.09718817e-01, 4.39485110e-01, + 1.93389833e-01, 6.80064195e-01, 4.43028888e-01, 5.56237485e-01, + 5.86496876e-01, 2.31257921e-01, 9.61202925e-01, 4.59793037e-01, + 5.61479458e-01, 8.77234565e-01, 6.05507053e-01, 2.03064972e-01, + 9.23516956e-01, 8.32189173e-01, 7.14766263e-01, 6.00909692e-01, + 4.75369769e-01, 2.52192755e-01, 1.01192654e-01, 1.82640578e-01, + 6.12079821e-01, 2.91314009e-01, 3.38339866e-01, 3.25244880e-01, + 4.28193726e-01, 8.38819570e-01, 2.66068046e-01, 5.77997609e-01, + 6.33842230e-01, 8.59226768e-01, 5.47721282e-01, 4.51013011e-01, + 1.41933382e-01, 1.58233176e-01, 7.36274517e-01, 8.77079133e-01, + 3.64500767e-01, 1.06048980e-01, 8.70183348e-01, 2.47642294e-01, + 1.63214503e-01, 7.76344248e-01, 2.63572879e-01, 9.04422771e-01, + 3.31230428e-01, 1.89025913e-01, 5.78611543e-01, 4.90528171e-01, + 7.64302624e-01, 3.01995592e-01, 6.13056209e-01, 8.13825825e-01, + 2.57329336e-01, 1.66718878e-01, 7.94592534e-01, 8.86334436e-01, + 6.10374964e-01, 2.87771705e-01, 5.45612401e-01, 4.37346903e-01, + 5.71538248e-01, 3.33973142e-02, 5.94744871e-01, 1.97806492e-01, + 1.22829759e-01, 2.47705589e-01, 1.29666014e-01, 1.72537025e-01, + 6.30226634e-01, 2.97305793e-01, 2.41658241e-01, 8.03958728e-01, + 6.56715667e-01, 2.16922109e-01, 3.87718346e-01, 7.24736100e-01, + 1.33184518e-01, 9.04524258e-01, 6.62300515e-02, 5.62362662e-01, + 8.70343960e-01, 1.43343922e-01, 7.57798720e-03, 6.87858407e-01, + 2.46865078e-01, 4.12706952e-01, 8.45243376e-01, 1.74276134e-01, + 4.21790519e-01, 7.07196936e-02, 2.67299318e-01, 2.66312175e-01, + 5.44482024e-01, 3.61060931e-01, 6.62722697e-01, 1.73284158e-01, + 8.92379290e-01, 8.42237465e-01, 5.88225553e-01, 3.19755374e-01, + 3.73048056e-01, 9.91540349e-01, 8.81802425e-01, 8.90415763e-01, + 3.21600364e-01, 5.75105765e-01, 2.64081085e-01, 6.35349535e-01, + 9.96842609e-01, 6.06757137e-01, 5.43231059e-01, 6.31772309e-01, + 1.28604009e-01, 3.85296434e-01, 9.66562077e-01, 9.24993565e-01, + 4.08646101e-01, 2.57195032e-01, 4.99559018e-01, 3.30590905e-01, + 2.75753925e-01, 4.24663958e-01, 1.99726024e-01, 6.09615831e-01, + 6.93912387e-02, 5.85029154e-01, 6.29352772e-01, 6.48178386e-01, + 3.77259531e-01, 5.04125465e-01, 5.56632153e-01, 2.48201529e-01, + 5.17730329e-01, 1.15699874e-01, 3.77347640e-02, 6.32627490e-01, + 9.86774371e-01, 7.70017805e-01, 7.88518452e-01, 4.74742065e-01, + 5.87766822e-01, 8.70387311e-01, 5.84113887e-01, 8.97441417e-01, + 1.78428301e-02, 3.98066215e-01, 1.34594086e-01, 7.18253859e-01, + 5.27009831e-01, 4.03080649e-01, 7.23440561e-01, 4.27520855e-01, + 3.68026660e-01, 7.11538788e-01, 6.67478414e-01, 2.32871924e-02, + 7.84880832e-01, 1.45336142e-01, 5.75668290e-01, 8.13004304e-01, + 2.05814529e-01, 9.47914810e-01, 6.44562983e-01, 8.48629796e-01, + 3.40464869e-01, 9.64319301e-01, 2.40078628e-01, 4.97184491e-01, + 7.40368203e-01, 5.74889758e-01, 1.72997562e-01, 7.76217188e-01, + 9.53144710e-02, 1.26942232e-02, 1.20893644e-01, 1.79072967e-01, + 6.96910859e-01, 6.21238277e-01, 9.62174814e-01, 9.86630646e-01, + 4.38483396e-01, 3.71595886e-01, 2.12381320e-01, 2.32395134e-01, + 1.98585395e-01, 9.44997425e-01, 2.99058186e-01, 2.82235207e-01, + 9.85614304e-01, 4.23673172e-01, 8.52717040e-01, 3.74433598e-01, + 9.16439272e-01, 6.08616508e-02, 2.79568454e-01, 6.89427200e-01, + 4.17028474e-01, 5.93868290e-01, 8.45153021e-01, 5.78780507e-01, + 8.99834348e-01, 3.94819540e-01, 1.58206722e-01, 6.09096431e-02, + 4.12309146e-01, 7.70781904e-01, 8.14126044e-01, 1.53080816e-02, + 1.29457919e-02, 8.34272811e-01, 5.84588027e-01, 5.01099790e-01, + 9.30890899e-01, 5.35819804e-01, 5.97723141e-01, 7.18482652e-02, + 7.64118304e-01, 6.00457393e-01, 1.51300499e-03, 7.32316014e-01, + 8.49944821e-01, 1.81182730e-01, 3.58653875e-01, 5.84862288e-01, + 7.49653254e-01, 6.25522929e-01, 9.80562135e-01, 1.03533965e-01, + 9.38744698e-01, 9.55887217e-01, 9.90515311e-01, 8.21634713e-01, + 6.77408570e-01, 2.99337349e-01, 2.45240019e-01, 8.14416151e-01, + 5.12592734e-01, 6.62767568e-01, 3.33403905e-01, 6.61761691e-01, + 7.49025551e-01, 5.87393442e-01, 2.07238651e-01, 4.68745758e-01, + 8.62035612e-01, 2.41516814e-01, 9.28035284e-01, 7.82432920e-01, + 7.32491002e-01, 3.20663204e-01, 5.59083780e-01, 7.05581001e-01, + 9.46183726e-01, 1.06006830e-01, 7.94781718e-01, 3.17211578e-01, + 4.12467767e-01, 1.55854106e-01, 1.40098765e-01, 6.89685903e-01, + 1.20028956e-01, 8.12410120e-01, 3.57096450e-01, 3.83630501e-01, + 3.81407329e-01, 5.44225083e-01, 1.74986076e-01, 4.77592620e-01, + 1.21944496e-01, 8.34478648e-01, 6.96490835e-01, 5.49827508e-01, + 5.47515640e-02, 1.70561469e-01, 2.77912184e-01, 4.04441910e-01, + 9.97193103e-01, 2.78272674e-01, 2.40056510e-02, 2.51853142e-01, + 3.34877656e-01, 2.31801168e-01, 2.46598202e-01, 8.52646141e-01, + 1.93409117e-01, 7.00411651e-01, 6.32489788e-01, 6.47269641e-02, + 2.51353228e-01, 8.17180352e-01, 4.62356863e-01, 5.27273877e-01, + 7.05969283e-01, 7.51765874e-01, 8.35492845e-01, 1.35506394e-01, + 2.61530320e-01, 3.20682888e-01, 3.18954597e-01, 3.07139485e-01, + 2.61962914e-01, 3.30613880e-01, 9.07200826e-02, 6.06202858e-01, + 8.36747305e-01, 3.55109173e-01, 4.94941940e-01, 1.25820220e-01, + 5.17048715e-02, 7.63000235e-02, 2.67274492e-01, 9.92138192e-01, + 2.78034163e-01, 6.65323883e-01, 7.54894601e-01, 2.19449131e-01, + 3.68750021e-01, 8.64247646e-01, 9.63748957e-01, 9.64750608e-01, + 2.24297632e-01, 3.39698952e-01, 9.94229340e-01, 6.97743370e-01, + 5.83625125e-01, 4.93055202e-01, 6.49122312e-01, 7.06328355e-01, + 1.26333641e-01, 3.80115175e-01, 2.28449133e-01, 2.22767825e-01, + 8.48205971e-01, 4.65934951e-01, 3.72549692e-01, 8.28956277e-01, + 3.36007180e-01, 2.35133544e-01, 5.59771139e-02, 9.54936584e-01, + 8.42164353e-01, 1.80391518e-01, 7.38924665e-01, 6.87395679e-01, + 1.99388436e-01, 5.99826951e-01, 9.66142085e-01, 7.51649586e-01, + 9.36096446e-01, 4.45870514e-01, 7.39956306e-01, 5.39705491e-01, + 3.69104773e-01, 6.82662294e-01, 8.56457822e-01, 4.07561951e-01, + 2.58861803e-01, 9.29644383e-01, 8.69500431e-01, 7.26341279e-01, + 6.00250300e-01, 2.57792159e-01, 6.47317808e-01, 9.74470843e-01, + 2.93003448e-01, 7.56220287e-01, 4.17122105e-01, 1.41783139e-01, + 6.45526915e-01, 7.94223310e-01, 2.30590052e-01, 5.73338874e-01, + 9.57619287e-01, 9.07885388e-01, 2.12735892e-01, 7.08940158e-01, + 1.50321098e-02, 8.20776954e-01, 1.40719237e-01, 3.22583922e-02, + 4.65625243e-01, 6.90417738e-01, 9.84318792e-01, 1.16394384e-01, + 6.35669181e-01, 9.37719355e-01, 2.74008417e-01, 4.57251005e-01, + 2.49569868e-01, 1.69433953e-02, 3.17662825e-02, 1.59587102e-01, + 7.83358255e-01, 6.77477003e-01, 7.83744446e-01, 7.62895899e-01, + 5.68819962e-01, 7.29331745e-01, 4.19426118e-01, 7.77328268e-01, + 5.88216444e-01, 9.97114683e-01, 4.77458782e-01, 1.07676258e-01, + 9.78465480e-01, 6.28285209e-02, 2.38397980e-01, 6.57846188e-01, + 5.48751029e-01, 1.24678227e-01, 7.58402711e-02, 9.71420260e-01, + 5.47550424e-01, 4.19757868e-01, 7.22052889e-01, 8.02164564e-01, + 4.43636390e-01, 1.58928137e-01, 4.24335396e-01, 2.12197261e-01, + 1.08836651e-01, 8.29052377e-01, 3.77888868e-01, 7.81084194e-01, + 7.78429714e-01, 3.90945690e-01, 6.51912226e-01, 2.88348822e-01, + 7.23901852e-01, 6.52715823e-01, 5.43731436e-02, 8.78512280e-01, + 6.60066267e-01, 8.20515209e-01, 4.42901526e-02, 5.13618862e-01, + 3.95231190e-01, 3.71209918e-01, 5.00722473e-01, 1.88894885e-01, + 9.06948616e-01, 8.52132921e-01, 1.29778705e-01, 1.43383305e-01, + 8.46342969e-01, 1.48545625e-01, 5.42216158e-01, 2.13416397e-01, + 6.73574223e-01, 5.22300826e-01, 5.86481435e-01, 4.58074668e-01, + 7.44556950e-02, 7.69430099e-02, 8.30101103e-01, 9.65982624e-01, + 6.09200262e-01, 6.71005983e-01, 9.92674306e-01, 9.92650495e-01, + 2.00438023e-01, 9.61423464e-01, 3.34473832e-01, 9.48197375e-01, + 4.39200472e-01, 7.76863250e-01, 5.69253833e-01, 5.70025518e-01, + 3.68976739e-01, 8.18171426e-01, 7.58481591e-02, 3.19808784e-01, + 4.57668288e-01, 1.44869379e-01, 6.78464367e-01, 1.66065777e-01, + 7.74631979e-01, 3.52758183e-01, 4.91845612e-01, 7.15016324e-01, + 4.94926235e-01, 8.50143184e-01, 7.68002689e-01, 2.80428378e-01, + 7.64445140e-01, 9.60741126e-01, 8.40453688e-01, 2.25481953e-01, + 5.84217713e-01, 6.63733112e-01, 8.20469002e-02, 5.03460927e-01, + 6.15793143e-01, 9.63304092e-01, 9.65981107e-01, 2.97332270e-01, + 4.54251208e-01, 9.26621241e-01, 1.08304032e-01, 5.43997217e-01, + 8.00307964e-01, 5.38281642e-01, 9.64531727e-01, 5.80528855e-01, + 6.92791319e-01, 4.21506325e-01, 3.42012123e-01, 4.12459301e-01, + 6.44631161e-01, 1.85067683e-02, 7.33214675e-01, 1.42917039e-01, + 5.51204686e-01, 2.97128845e-01, 6.87057014e-01, 3.28233924e-01, + 8.97879000e-01, 9.78933901e-01, 1.04951389e-01, 2.50031726e-01, + 9.95941262e-01, 5.83330828e-01, 5.72222748e-01, 2.88462307e-01, + 3.42147380e-01, 7.82169432e-01, 3.70059110e-01, 4.52782248e-01, + 8.07919395e-01, 3.95487902e-01, 7.02669357e-02, 8.71997657e-01, + 2.05374408e-01, 2.39741123e-01, 7.95127425e-01, 3.47019036e-01, + 5.06856826e-01, 3.20973776e-01, 2.05599215e-01, 4.03323806e-01, + 2.02475510e-01, 1.76500710e-01, 7.45973346e-01, 8.02962844e-01, + 2.86354442e-01, 5.95489096e-01, 7.43402988e-01, 2.62402528e-01, + 9.79921875e-01, 2.46865962e-01, 2.84770027e-01, 2.27352503e-02, + 7.96055075e-02, 2.12807086e-01, 9.82460388e-01, 5.59973629e-01, + 8.88765969e-01, 5.58124493e-01, 5.67634068e-01, 7.21318629e-01, + 5.28885789e-01, 4.43899006e-01, 3.89530240e-01, 5.31093600e-01, + 5.86830474e-01, 8.51280942e-01, 9.21934422e-01, 4.24711396e-01, + 5.55468787e-01, 2.36251878e-01, 6.57752151e-01, 8.01006332e-01, + 1.40256336e-01, 1.66563629e-01, 4.01277343e-01, 4.50459390e-01, + 7.94146451e-01, 4.34760883e-01, 8.24390211e-01, 7.02275970e-01, + 3.95060222e-01, 5.73282605e-02, 8.71138034e-03, 7.28635465e-01, + 8.45552224e-01, 4.70925234e-01, 6.78796265e-02, 2.07263097e-01, + 5.86946139e-01, 9.06559029e-01, 6.51919310e-01, 7.60877329e-01, + 6.76870797e-01, 4.00789965e-01, 3.93900812e-01, 3.51690776e-01, + 5.23143230e-04, 3.78857317e-01, 5.43222132e-01, 8.16578228e-01, + 9.30324851e-01, 6.46214332e-01, 2.61310347e-01, 2.70396034e-02, + 7.32481401e-01, 5.81694842e-01, 7.58738779e-03, 7.90227361e-01, + 3.00126457e-01, 4.14882874e-02, 7.08497948e-01, 5.60693385e-01, + 5.47778566e-02, 3.39501905e-01, 9.68503497e-01, 2.82392648e-01, + 6.19676991e-01, 5.58693445e-01, 2.42016331e-01, 6.59966678e-01, + 9.39823398e-02, 8.91229971e-01, 3.64346405e-01, 2.95260491e-01, + 1.36980210e-01, 3.30952220e-01, 7.43274694e-01, 4.48712998e-01, + 5.79190352e-01, 5.05283697e-02, 2.46807884e-01, 6.58511828e-01, + 7.35609681e-01, 9.33688813e-01, 7.40011895e-03, 9.56898332e-01, + 2.60040059e-01, 8.32883745e-01, 3.99693073e-01, 2.42512322e-01, + 5.20237365e-01, 3.44008476e-01, 9.06945518e-01, 6.30303009e-01, + 4.15536907e-01, 7.75681961e-01, 8.68198307e-01, 1.89745356e-01, + 9.58812180e-01, 3.39231168e-01, 7.13284513e-01, 5.44619342e-01, + 6.90752904e-01, 3.41919481e-01, 9.17002377e-01, 4.42660426e-01, + 2.97611223e-01, 2.09665584e-01, 7.15700835e-01, 4.08069844e-01, + 9.37477590e-01, 7.31847963e-01, 2.24883023e-01, 6.42080345e-01, + 5.62037302e-01, 3.66030416e-02, 1.26555140e-01, 2.66109804e-01, + 4.11514421e-01, 6.89398564e-01, 3.24382926e-01, 7.09235595e-01, + 8.36059819e-01, 1.54755053e-01, 2.55443940e-01, 1.38511230e-01, + 1.28580165e-01, 4.65390959e-01, 5.74969736e-01, 1.87437843e-01, + 3.08632637e-01, 9.98398382e-01, 8.31796483e-01, 7.07153453e-01, + 4.50038297e-02, 7.44671234e-03, 1.86645396e-01, 8.99905024e-01, + 4.75494879e-01, 2.75352305e-01, 6.19095221e-01, 9.88322601e-01, + 7.43618748e-01, 5.98011517e-01, 6.11113136e-01, 9.59259852e-01, + 6.46648391e-01, 1.94647377e-02, 6.13853105e-02, 1.36690848e-01, + 6.59128521e-01, 8.29382985e-02, 7.26147650e-01, 9.12885719e-01, + 7.11153104e-01, 4.37900399e-01, 2.14801191e-01, 5.73226766e-01, + 4.47518472e-02, 6.49675931e-01, 2.03952495e-01, 9.71144660e-01, + 7.02592556e-01, 4.16915759e-01, 8.10849851e-01, 1.31426871e-01, + 5.34316452e-01, 3.73126310e-02, 7.81773874e-01, 4.16333390e-01, + 9.81162386e-01, 3.85792561e-01, 6.09930953e-02, 5.31823785e-02, + 5.22322062e-01, 7.74411477e-01, 4.86276490e-01, 5.50963925e-01, + 2.33599095e-01, 3.98549372e-01, 4.82391321e-01, 5.70988844e-01, + 1.78844466e-01, 9.49290226e-01, 4.74758248e-01, 2.51411034e-01, + 6.26682370e-01, 5.27678789e-02, 5.18200357e-01, 9.91857191e-01, + 2.55883271e-01, 9.12084937e-01, 4.98020624e-01, 2.46761272e-01, + 3.74236562e-01, 3.25448819e-01, 6.15502212e-01, 5.56337605e-02, + 2.77707979e-01, 9.12936667e-01, 7.69895125e-01, 9.55639929e-01, + 8.27437886e-02, 5.72907267e-01, 1.29786295e-02, 6.35965414e-01, + 5.76948360e-01, 6.78419034e-01, 8.85029727e-01, 7.54937124e-01, + 1.61134035e-02, 8.62421529e-01, 7.60092328e-01, 2.04175394e-01, + 7.06165401e-01, 2.22521842e-01, 2.99530561e-01, 9.83097374e-01, + 7.52501116e-01, 4.77643358e-01, 8.48989955e-01, 7.07797363e-01, + 4.57460071e-01, 8.76173059e-01, 7.70355145e-01, 9.19190360e-01, + 1.76969224e-01, 6.00997624e-01, 5.45117516e-01, 3.78660623e-01, + 8.95231199e-01, 5.13465555e-01, 7.14449756e-01, 7.67966306e-01, + 8.89714449e-01, 7.14009679e-02, 5.52928812e-01, 7.86021850e-01, + 9.41163034e-01, 4.67822478e-01, 8.05915121e-02, 5.30276186e-01, + 7.65467203e-01, 3.73808835e-01, 4.91156378e-01, 3.58664602e-01, + 2.26904088e-01, 3.16859132e-01, 3.73453110e-01, 6.30708292e-01, + 5.12523662e-01, 8.81846398e-01, 6.92017219e-01, 9.48869807e-01, + 7.92591089e-01, 9.24534687e-01, 3.28455072e-01, 7.45136433e-01, + 3.40401009e-01, 3.40231921e-01, 4.77734018e-01, 6.50807174e-01, + 7.98767642e-01, 7.06227188e-01, 6.25502118e-01, 8.91886969e-01, + 6.06700448e-01, 3.41539951e-01, 9.32214524e-01, 4.34983330e-01, + 3.45254713e-01, 3.57136166e-01, 9.85057476e-01, 6.65219177e-01, + 6.79501220e-01, 4.20034542e-01, 3.56116781e-02, 3.61296822e-01, + 1.28159608e-01, 9.39005671e-01, 4.92631448e-01, 2.24843838e-01, + 2.62851024e-01, 4.79554042e-02, 2.97862523e-01, 8.19822181e-01, + 1.47177192e-01, 5.31670502e-01, 2.76609400e-02, 7.58205905e-01, + 8.45054829e-01, 3.94621114e-01, 1.40304529e-01, 2.81893546e-01, + 4.03035670e-01, 9.42132100e-01, 2.97318846e-01, 2.27801447e-01, + 4.05697432e-01, 4.87274269e-01, 3.00716313e-01, 4.82574170e-02, + 4.44931201e-01, 8.38566584e-01, 2.54748403e-01, 7.95011807e-01, + 5.39238275e-01, 5.30986168e-01, 4.98400033e-01, 9.89188053e-01, + 3.61317622e-01, 1.90124545e-01, 2.55053949e-01, 5.99007609e-01, + 3.17359682e-01, 9.47342893e-01, 1.39071107e-01, 7.91886755e-01, + 1.44858792e-01, 9.99004213e-01, 5.58560202e-02, 8.46648208e-02, + 6.87166284e-01, 8.35783607e-01, 4.81347011e-01, 5.84029341e-01, + 2.02951199e-01, 3.95813602e-01, 9.49057551e-02, 4.47859372e-02, + 2.68994839e-01, 7.07165004e-01, 8.87825246e-01, 6.12770437e-01, + 2.34321343e-01, 5.85709437e-01, 8.72671869e-02, 1.39896827e-01, + 5.09333843e-01, 7.27710068e-01, 7.38663637e-01, 5.50438938e-01, + 9.31590149e-01, 4.04769063e-01, 2.73018682e-02, 5.07490305e-01, + 8.74367997e-01, 6.77101075e-01, 2.33192320e-01, 5.09244160e-01, + 6.82129724e-01, 9.93948690e-01, 4.36099996e-01, 4.68337581e-02, + 6.22690760e-01, 4.44871189e-01, 3.90277745e-01, 7.70136882e-01, + 8.08790015e-01, 3.85178146e-02, 1.74645856e-01, 4.44510159e-02, + 5.47737664e-01, 8.02671146e-01, 2.78333350e-01, 6.37671858e-01, + 7.00968580e-01, 9.43903614e-01, 7.66194212e-01, 1.32352701e-01, + 6.36437044e-01, 2.79465972e-01, 6.76586377e-02, 1.07716871e-01, + 4.42186585e-01, 7.08154504e-01, 9.38951281e-01, 4.01040842e-01, + 7.77139248e-01, 5.16737445e-01, 4.71288711e-01, 5.68391592e-01, + 4.53398096e-01, 5.25239515e-01, 1.23416489e-01, 7.00305807e-01, + 3.55456337e-01, 6.02767565e-01, 4.65117973e-01, 3.66442098e-01, + 3.59252014e-01, 9.77318209e-02, 2.54376451e-01, 9.92153383e-01, + 8.44311596e-01, 3.33511657e-01, 3.21187113e-01, 9.44155515e-01, + 9.58279383e-01, 6.19696671e-01, 6.83133956e-01, 9.53238889e-01, + 9.52786182e-01, 7.70795489e-01, 1.19985029e-01, 8.80668885e-01, + 7.92041990e-01, 5.34508783e-01, 8.61126458e-01, 7.30015303e-01, + 2.44730644e-01, 3.85520206e-01, 5.14773006e-01, 9.30435191e-01, + 2.90506950e-01, 1.59853133e-01, 5.33678023e-01, 4.06483043e-01, + 9.83312639e-01, 7.92208535e-01, 4.48549604e-01, 9.29596783e-01, + 8.29209388e-01, 4.13746197e-01, 2.78522894e-01, 1.24698598e-01, + 9.95279157e-01, 4.97658654e-01, 3.47725026e-01, 8.12280996e-01, + 2.05401829e-01, 6.11935271e-01, 6.64070705e-01, 6.97104230e-01, + 5.20320333e-01, 8.07002465e-02, 2.65561088e-01, 5.04476612e-01, + 2.53677297e-01, 2.22037103e-02, 5.56679999e-01, 2.13880244e-02, + 5.26273785e-02, 9.16837638e-01, 8.06240972e-01, 7.28558889e-01, + 3.98628439e-01, 4.64297787e-01, 1.53553483e-01, 1.64207909e-01, + 6.04853572e-01, 5.36962911e-01, 5.18696963e-01, 3.55893557e-01, + 1.74758575e-02, 3.08559150e-01, 9.52638311e-01, 8.47241893e-01, + 5.00552846e-01, 2.56364563e-01, 1.23799145e-01, 1.47851097e-01, + 3.45581385e-01, 9.03615026e-01, 2.23265175e-01, 4.96256433e-01, + 7.67961045e-01, 7.09507947e-01, 6.01350814e-01, 1.31313992e-01, + 6.91281767e-01, 3.45817624e-01, 2.84693078e-02, 3.07414436e-01, + 3.33561761e-01, 8.14277773e-01, 4.36154703e-01, 7.78464078e-01, + 6.40600546e-02, 8.98374698e-01, 1.48836952e-01, 6.87839652e-01, + 2.58203274e-01, 2.53358829e-02, 2.64164118e-01, 2.24107570e-01, + 9.60626248e-01, 6.44587610e-01, 2.26682168e-01, 1.24678631e-01, + 1.37189111e-01, 5.47457097e-01, 2.45986556e-01, 6.27171911e-01, + 4.62105354e-01, 5.45884629e-01, 3.98675650e-01, 9.20427902e-02, + 5.79638610e-01, 6.03795142e-01, 5.95348766e-01, 1.24123121e-01, + 3.59812080e-01, 8.97200870e-01, 1.36096808e-01, 9.21413055e-01, + 2.30924025e-01, 2.32271947e-01, 8.47191024e-01, 4.44227105e-01, + 5.02807640e-01, 8.87944464e-01, 6.73280097e-01, 9.00854692e-01, + 4.45951722e-01, 8.44607166e-01, 9.30937171e-01, 2.78999887e-01, + 5.85286759e-01, 7.78448585e-01, 7.42990033e-01, 4.60412735e-01, + 3.68970066e-01, 8.44483407e-01, 9.76292697e-01, 5.57247712e-01, + 2.90144827e-02, 6.40377843e-02, 5.04281811e-01, 3.08020642e-01, + 6.73448304e-01, 6.41708285e-01, 3.20919116e-01, 8.60140279e-02, + 8.76827989e-01, 3.21997580e-01, 2.47139868e-01, 2.81166389e-01, + 6.49057366e-01, 4.43597391e-01, 6.80117301e-02, 6.92262024e-01, + 2.89536739e-01, 5.18961403e-01, 7.51654551e-01, 1.07850946e-01, + 9.13298767e-01, 6.20937411e-01, 9.51990513e-01, 4.60408615e-02, + 5.95896084e-01, 2.40755336e-01, 7.04904710e-01, 8.89364841e-01, + 8.12797679e-01, 4.59725452e-01, 5.42419112e-01, 5.83490243e-01, + 6.57364847e-01, 7.10158049e-01, 9.31392924e-01, 3.42382488e-01, + 2.43136684e-01, 7.94487603e-01, 1.33636000e-01, 5.98565779e-01, + 4.79356515e-01, 2.78107779e-01, 1.02616971e-01, 7.97586145e-01, + 5.25068076e-01, 5.81882776e-01, 6.18754490e-02, 4.66314066e-01, + 1.95333916e-01, 3.44818394e-01, 3.24977977e-01, 2.56977928e-01, + 3.38226285e-01, 9.39668269e-02, 3.96353133e-01, 7.88433242e-01, + 8.47038548e-01, 6.88273075e-01, 3.15373368e-01, 1.66250014e-01, + 8.14076813e-01, 4.19474154e-01, 2.31482016e-01, 3.98914298e-01, + 7.90044337e-01, 1.78959492e-01, 6.56782330e-01, 4.51813294e-01, + 6.23312999e-01, 8.31178219e-01, 6.53066574e-01, 9.12065522e-01, + 5.56236102e-02, 4.36703335e-01, 2.53798590e-01, 9.43292997e-01, + 5.03324145e-02, 1.76916441e-01, 2.26853091e-01, 3.55773145e-01, + 3.20730959e-01, 7.51416299e-01, 9.52854353e-01, 3.23625963e-01, + 7.30134884e-01, 7.56065705e-02, 1.59748525e-01, 1.93278694e-01, + 8.00096778e-01, 1.10635984e-01, 4.55346304e-01, 6.71278245e-01, + 6.67190531e-01, 6.39218459e-01, 4.28078739e-01, 9.02470778e-01, + 4.48024608e-01, 5.33436692e-01, 6.77335653e-02, 6.31257708e-01, + 3.17529787e-01, 6.15566019e-01, 5.88019537e-01, 1.28779729e-01, + 3.24475462e-02, 1.29975240e-01, 3.96632091e-01, 6.68507605e-01, + 5.98634700e-01, 6.98114204e-01, 2.85172283e-01, 5.92092760e-01, + 9.43681575e-02, 3.11732964e-01, 6.69661926e-01, 6.19033207e-02, + 3.15569199e-01, 8.24018427e-01, 2.72827084e-01, 2.12553118e-02, + 5.44778065e-01, 4.26126668e-01, 3.43077971e-01, 9.38969273e-01, + 6.79067818e-01, 8.20544923e-01, 3.91665685e-01, 8.40458227e-02, + 4.68754453e-01, 7.94008161e-01, 6.28415682e-01, 4.10742878e-01, + 6.38712164e-01, 2.48962420e-02, 5.91028828e-01, 9.58334342e-01, + 8.69295404e-01, 2.53102989e-01, 5.17612544e-01, 8.16636860e-01, + 4.54036299e-01, 9.87268903e-01, 6.42350149e-01, 8.94638842e-01, + 2.81913893e-01, 7.38329591e-01, 4.97222656e-01, 1.50687871e-01, + 6.58082501e-01, 9.01998958e-01, 8.78885705e-01, 5.72693786e-02, + 5.66994609e-01, 1.86903723e-01, 3.03128279e-02, 6.55577712e-01, + 1.48136670e-01, 3.66744929e-02, 4.00643997e-01, 2.16833884e-01, + 4.28637098e-01, 5.93251499e-01, 3.10099576e-01, 3.56347907e-01, + 4.80633919e-01, 6.95479794e-01, 3.82901881e-01, 4.86445719e-01, + 6.90776257e-01, 5.27943762e-01, 1.54057492e-01, 3.81399626e-01, + 5.27223710e-01, 2.75750893e-01, 9.06080430e-01, 3.68589759e-01, + 5.58721041e-01, 3.88216990e-01, 4.20036648e-01, 3.90405436e-01, + 8.35696253e-02, 6.47239540e-01, 9.02878426e-01, 2.20779035e-01, + 2.09764394e-01, 9.01694507e-01, 4.17614713e-01, 2.11505870e-01, + 3.04049682e-01, 6.50487405e-01, 5.79122544e-01, 8.85505215e-02, + 5.41049364e-01, 9.58523804e-01, 7.65869000e-02, 8.18691445e-01, + 7.56380310e-01, 6.91066947e-02, 5.58165939e-01, 3.33783422e-01, + 8.10890357e-01, 8.02739567e-02, 4.60010558e-01, 6.02989674e-01, + 8.18790942e-01, 9.51333826e-01, 7.58956860e-01, 2.97026768e-01, + 4.89478781e-01, 7.32401666e-01, 5.59447345e-01, 8.89480242e-01, + 4.60698134e-01, 5.59130888e-01, 6.73016830e-01, 3.98687801e-01, + 1.62702070e-01, 9.90090958e-01, 3.70339710e-01, 9.69956667e-01, + 2.84279349e-01, 5.33610153e-01, 4.23134696e-01, 1.70047738e-01, + 1.30152889e-03, 9.88960317e-01, 4.70958919e-01, 6.11701914e-01, + 3.34924421e-01, 6.18826931e-01, 6.75401088e-01, 9.78653009e-01, + 8.24862312e-01, 7.35813539e-02, 5.92246958e-01, 1.73297526e-01, + 2.71078644e-01, 4.31840115e-01, 6.42635735e-01, 6.65594543e-01, + 6.87719832e-01, 2.85053867e-01, 6.72791677e-01, 8.13775595e-01, + 6.41472912e-01, 1.64871174e-01, 4.04255199e-01, 1.34913794e-01, + 5.80228604e-01, 7.12544926e-01, 6.67000888e-04, 8.60751469e-01, + 7.73103686e-01, 5.09803470e-01, 1.38742504e-01, 4.44729321e-01, + 6.04426510e-01, 8.51775434e-01, 9.20191017e-01, 2.23018119e-01, + 1.13988927e-01, 3.27425393e-02, 7.72343135e-01, 2.59325047e-02, + 7.58667597e-01, 3.94506976e-01, 1.51791171e-01, 8.66853950e-01, + 9.78480502e-01, 3.24678356e-01, 8.43552026e-01, 2.93808597e-01, + 9.75134987e-01, 8.47768039e-01, 7.74106338e-01, 5.90672167e-01, + 8.34666097e-01, 1.68905661e-01, 7.64858239e-01, 1.80665783e-02, + 8.03131088e-01, 8.89208355e-01, 6.37933426e-01, 1.59727271e-01, + 7.51656604e-02, 2.08827448e-01, 8.84935456e-01, 6.72354715e-01, + 1.52415078e-01, 6.65886720e-01, 5.82533752e-01, 4.16740892e-01, + 1.27180431e-01, 9.81197907e-01, 2.02190637e-01, 4.28024097e-01, + 4.98733443e-01, 4.87579983e-01, 4.84558001e-01, 2.92440812e-01, + 2.52710137e-01, 7.79116604e-01, 1.75135175e-01, 9.11629390e-01, + 3.67603592e-01, 4.00705048e-02, 2.78911824e-01, 9.04293122e-01, + 5.73009839e-02, 4.67027747e-01, 7.46474494e-01, 2.89453700e-01, + 7.85534327e-01, 3.22750344e-01, 2.66166390e-01, 1.26029132e-01, + 4.42315884e-01, 9.34142069e-01, 8.81743162e-01, 6.09369659e-01, + 9.44759200e-01, 9.00191783e-02, 1.64306150e-01, 5.99951432e-01, + 2.86214068e-01, 2.69497132e-01, 1.45099944e-01, 7.41321191e-01, + 5.93012397e-01, 1.50296977e-01, 1.40914168e-01, 5.42359671e-01, + 9.45060202e-01, 4.11114012e-01, 7.06014805e-01, 2.93229759e-02, + 2.63689713e-01, 5.50893307e-01, 5.71239434e-01, 6.36056158e-01, + 5.04706937e-01, 2.49390958e-01, 7.11128783e-01, 6.12824706e-01, + 6.65674403e-01, 9.75215008e-01, 5.74364962e-01, 8.21659629e-02, + 7.81897800e-01, 9.94561491e-01, 7.56646794e-01, 7.84591196e-01, + 5.47862271e-01, 2.07693027e-01, 6.61642364e-01, 5.46043761e-01, + 2.69485297e-01, 6.51595071e-01, 5.96015962e-01, 9.78866293e-01, + 1.12644756e-01, 2.08395393e-01, 2.39137730e-01, 4.55512794e-01, + 2.58054477e-01, 3.51078674e-01, 7.18697643e-01, 3.04283300e-01, + 8.85772053e-01, 1.07335595e-01, 1.11016666e-02, 4.66941811e-02, + 8.57695378e-01, 8.84085764e-01, 9.51419283e-01, 2.85808421e-01, + 2.94466675e-01, 8.95751848e-01, 9.51237288e-01, 8.70098323e-01, + 6.31355220e-01, 4.83351553e-01, 2.73303162e-01, 4.21021423e-01, + 5.56289349e-01, 3.09791015e-01, 9.89152931e-01, 8.30264199e-01, + 3.35968172e-01, 3.04151491e-01, 6.25620761e-01, 6.29068530e-01, + 1.09388475e-01, 5.44286763e-01, 2.06621700e-01, 5.85537407e-01, + 4.76106882e-01, 4.91342872e-01, 3.61321390e-01, 3.07561371e-01, + 1.56907444e-01, 1.49327630e-01, 2.86946091e-01, 2.57305975e-01, + 1.90511094e-01, 4.30100103e-01, 4.81990839e-02, 1.96229007e-02, + 9.39192833e-01, 1.70695395e-01, 8.68217041e-01, 1.42434092e-01, + 7.20000941e-01, 3.64174999e-01, 3.14028022e-01, 3.66794518e-01, + 1.97255141e-01, 5.01957854e-01, 7.50719103e-01, 6.84012437e-01, + 9.93919147e-01, 4.96941433e-01, 1.40961326e-01, 3.29951112e-01, + 9.64597524e-01, 2.04951224e-01, 3.69705513e-01, 4.11519663e-01, + 2.24723664e-01, 5.16087119e-01, 6.19955216e-01, 6.45240753e-02, + 3.77989995e-01, 1.87488656e-01, 7.37072960e-01, 1.94733439e-01, + 8.84650393e-01, 4.85073667e-01, 3.30942322e-01, 8.45970216e-01, + 1.85874456e-01, 3.95400662e-01, 9.42358280e-01, 7.48086224e-01, + 7.66473481e-01, 4.66850330e-01, 7.66936431e-01, 9.45319467e-01, + 2.58343803e-02, 2.19800750e-01, 5.19807098e-01, 8.26417654e-01, + 2.88910925e-02, 8.18651406e-01, 6.08262251e-01, 1.52200977e-01, + 5.16417506e-01, 8.59279352e-01, 5.24398933e-01, 1.04438632e-02, + 3.51627870e-01, 2.92104868e-01, 7.26154766e-01, 4.40209056e-01, + 7.43595262e-01, 7.36120016e-01, 4.66905976e-01, 4.99198690e-01, + 8.66496044e-01, 5.07439810e-01, 8.45398854e-01, 3.99111687e-01, + 7.66914290e-01, 5.40475958e-01, 6.17083815e-02, 4.86618164e-01, + 8.90140414e-01, 7.74410339e-01, 2.57394735e-01, 1.34582552e-01, + 1.37913779e-01, 1.40711021e-01, 6.20421361e-01, 6.17049397e-01, + 3.91919124e-02, 5.63344778e-01, 9.71582320e-01, 4.78070735e-01, + 6.39489999e-01, 5.54851510e-01, 6.20847233e-01, 2.48655091e-01, + 1.12036306e-01, 3.58044253e-01, 2.40563526e-01, 6.73866370e-01, + 8.32916319e-02, 9.42617969e-01, 6.85175163e-01, 8.86257647e-01, + 9.03598607e-01, 1.12067722e-01, 5.83994162e-01, 2.09640837e-01, + 4.13083435e-01, 1.99729861e-01, 7.48709636e-01, 1.58800314e-01, + 9.90927520e-01, 6.17744652e-02, 9.22245437e-01, 4.00679715e-02, + 4.28910311e-02, 6.32849146e-01, 2.89661878e-01, 4.46577741e-02, + 6.69896933e-01, 8.61051905e-01, 4.95476982e-01, 3.65595473e-01, + 7.01348878e-01, 1.22944294e-01, 6.45093371e-01, 4.81853573e-01, + 3.06177165e-01, 1.33241038e-01, 6.74666644e-01, 5.24154249e-01, + 4.20615272e-01, 1.01289416e-01, 8.84843584e-01, 8.14617259e-01, + 5.44945190e-01, 9.46511161e-01, 2.86147551e-01, 7.75739380e-01, + 5.54025247e-01, 5.91516168e-01, 7.41019496e-01, 3.39481973e-01, + 5.93373252e-01, 8.91760043e-01, 7.66931733e-01, 9.60071640e-01, + 5.68491119e-01, 7.27415296e-01, 3.10274385e-01, 2.48576743e-01, + 2.97305018e-01, 9.35289052e-01, 1.18540593e-01, 3.33102524e-02, + 3.63421806e-01, 7.47599050e-01, 2.61003865e-01, 3.51395142e-01, + 2.71370493e-01, 1.30290514e-01, 3.67409777e-01, 6.94999340e-01, + 3.50246710e-01, 4.40475356e-01, 4.83887311e-01, 6.70694419e-02, + 7.45450089e-01, 9.33630210e-01, 4.84844933e-01, 2.27515375e-01, + 5.20061854e-01, 5.66589164e-01, 5.46473362e-01, 8.55681458e-01, + 4.75649398e-02, 1.76488156e-01, 8.01700086e-01, 5.54733265e-01, + 9.87897914e-01, 5.45297384e-01, 4.03127520e-01, 9.62811661e-02, + 9.84187447e-01, 1.48308439e-01, 5.19639256e-01, 8.54746173e-01, + 5.49394002e-01, 8.03920086e-01, 5.01094073e-02, 7.31640681e-01, + 9.96655364e-01, 5.28259093e-01, 3.53773424e-01, 3.30416526e-01, + 7.28755138e-01, 5.00799785e-02, 6.21256958e-01, 9.76905213e-01, + 7.31860484e-01, 6.70918180e-01, 8.88697690e-01, 2.25997409e-01, + 8.61316842e-01, 8.34051782e-01, 5.61456480e-02, 5.05870572e-01, + 2.43314209e-01, 9.79258153e-01, 9.84103549e-01, 9.49817330e-01, + 5.22339401e-01, 1.75281414e-01, 1.27118190e-01, 8.34684239e-01, + 8.78523544e-02, 6.31105173e-01, 6.88690954e-01, 8.86817787e-01, + 4.24203485e-01, 6.18690633e-01, 8.58499444e-01, 3.40699490e-01, + 4.09048047e-01, 5.28199962e-01, 8.68438128e-01, 6.76980326e-01, + 9.96602335e-02, 6.35910470e-01, 2.02782704e-01, 1.34407251e-01, + 4.33024477e-01, 5.55471376e-01, 8.96482906e-01, 9.81521658e-01, + 9.28311782e-02, 9.36185775e-01, 3.36119211e-01, 5.90722090e-01, + 9.57876633e-02, 8.86488186e-01, 5.88546129e-01, 2.68689883e-01, + 7.65628884e-01, 5.17093745e-01, 3.27562280e-02, 4.46403474e-01, + 1.18580286e-01, 7.60833006e-02, 4.26251283e-01, 4.07476469e-01, + 8.07665335e-01, 6.70887688e-01, 6.81027151e-01, 3.16472677e-01, + 8.04942212e-01, 4.67548015e-01, 8.57818737e-01, 3.54376386e-01, + 3.87257380e-01, 3.96796899e-01, 6.07198026e-01, 9.84424697e-01, + 7.17794237e-01, 4.17304670e-02, 3.06700354e-01, 1.06816213e-01, + 3.62244493e-02, 5.96704126e-01, 6.23022199e-01, 8.63719677e-01, + 9.77772101e-01, 1.60840381e-01, 6.67476766e-01, 6.89678502e-01, + 9.78919114e-01, 2.98506375e-01, 3.73451890e-01, 2.79166438e-01, + 5.12995093e-01, 6.52845350e-01, 1.36708802e-01, 5.26858830e-02, + 7.91953105e-02, 4.10402396e-01, 6.85485684e-02, 9.16645020e-01, + 9.53487860e-01, 5.58362475e-01, 9.55041712e-01, 2.12343000e-01, + 2.09592841e-01, 5.77764894e-01, 7.55958181e-01, 3.97197079e-01, + 2.86547859e-01, 8.08694338e-01, 8.11330240e-01, 8.07997388e-02, + 6.02588256e-02, 3.58090677e-01, 6.31696898e-01, 7.25765761e-01, + 3.03867973e-01, 5.22208307e-01, 5.95113511e-01, 1.93917248e-01, + 6.93336484e-01, 4.68945831e-01, 5.71711340e-01, 4.65814532e-02, + 4.17931405e-01, 5.58218729e-01, 2.05405733e-01, 4.26406104e-01, + 2.55672483e-01, 8.50783826e-01, 8.41007957e-01, 2.90479497e-01, + 9.37725770e-01, 5.97105822e-01, 9.38180993e-01, 8.04185991e-01, + 8.78757367e-01, 7.97791945e-02, 2.54571978e-01, 7.33486785e-01, + 2.72100542e-01, 1.80360266e-01, 9.18105933e-01, 5.98155782e-01, + 9.57288341e-01, 2.79165869e-01, 9.51533064e-01, 6.45709886e-01, + 3.45390961e-01, 1.06156187e-01, 2.65540209e-01, 7.81212006e-01, + 6.13245340e-01, 2.69448654e-01, 5.59184842e-01, 6.78933623e-02, + 3.72053972e-01, 8.39822146e-01, 6.96559208e-01, 5.69445313e-01, + 1.94521445e-01, 2.99575456e-01, 7.14622666e-01, 2.58761360e-01, + 2.98778925e-01, 8.88073102e-01, 8.38053457e-01, 6.34929822e-01, + 8.29036472e-01, 6.72925777e-01, 3.94432278e-01, 4.61465287e-01, + 1.01100142e-01, 3.65136758e-01, 7.00952009e-01, 8.83561378e-01, + 3.66132754e-01, 5.09617437e-01, 1.28240885e-01, 9.05218645e-01, + 6.34551163e-01, 4.82098991e-01, 4.30733341e-01, 4.57745273e-01, + 5.80988446e-01, 7.58945533e-01, 5.21329399e-01, 4.41800584e-01, + 9.10839776e-02, 2.85592792e-01, 3.65260118e-01, 8.20410633e-01, + 9.51834125e-01, 7.26481208e-01, 6.46535207e-01, 4.60471555e-01, + 5.70667102e-01, 4.65408689e-01, 6.79807669e-01, 4.12960878e-01, + 6.01566393e-02, 4.41279309e-01, 8.57785159e-01, 1.94541490e-01, + 5.71581150e-01, 1.00558574e-01, 9.13180656e-01, 7.40378183e-01, + 2.79671457e-03, 2.28238515e-01, 8.54025954e-02, 2.25996397e-01, + 6.01997716e-01, 6.68228468e-01, 8.29994413e-01, 4.45582014e-02, + 8.33229016e-01, 9.68124455e-02, 6.45213939e-02, 9.08902320e-01, + 6.38630530e-01, 6.49904305e-01, 6.70210551e-01, 1.39084935e-01, + 6.53865487e-01, 3.72781167e-01, 9.11734645e-01, 3.92019562e-01, + 1.64879257e-01, 4.34820447e-01, 1.15044546e-02, 6.08003611e-01, + 3.81915126e-01, 4.46509769e-01, 5.72206499e-01, 4.85417514e-01, + 9.47774157e-01, 6.45287203e-01, 5.73971320e-01, 6.30085523e-01, + 6.37175073e-01, 1.57243264e-01, 9.68008267e-01, 6.03855918e-01, + 3.18754354e-01, 7.51607577e-01, 5.33013189e-01, 1.76648331e-01, + 5.42004463e-01, 1.05083006e-01, 4.80024812e-01, 5.53574557e-01, + 6.92947928e-01, 6.07564794e-02, 5.24270448e-01, 7.67120242e-01, + 1.72192574e-01, 6.35344204e-01, 2.64153698e-01, 8.42507593e-01, + 7.12767721e-01, 1.87450704e-01, 2.35616309e-01, 5.14739313e-01, + 7.04592123e-01, 2.49750362e-01, 4.85957579e-01, 9.30340995e-01, + 1.06283711e-01, 2.86754792e-01, 8.41251316e-01, 8.44712181e-01, + 7.57821474e-01, 5.22651716e-03, 4.32943870e-01, 9.26185554e-01, + 9.21796029e-01, 7.80535685e-01, 8.60970172e-02, 6.67827266e-01, + 6.64218856e-01, 3.57040990e-01, 3.61147185e-01, 9.08323924e-01, + 1.21250966e-01, 4.18836858e-02, 5.65714227e-01, 6.34819777e-01, + 6.65300013e-01, 2.80393985e-01, 3.12632326e-01, 7.93204664e-01, + 7.28994032e-01, 3.61832217e-01, 3.77784224e-01, 8.48436301e-01, + 8.43843665e-01, 2.14772052e-02, 4.65146482e-01, 7.59322206e-01, + 5.70665884e-01, 6.69850020e-01, 5.56189734e-01, 4.06630022e-01, + 4.60067954e-01, 1.20587913e-01, 4.92001607e-01, 9.52827962e-01, + 9.60397049e-01, 4.95977104e-01, 7.33706091e-01, 6.70250679e-01, + 1.36700477e-01, 1.37437503e-01, 9.89505781e-01, 9.20815652e-01, + 2.30390726e-01, 4.76175819e-02, 9.14609445e-01, 2.57292849e-01, + 9.15615749e-01, 4.10536833e-01, 2.75390187e-01, 3.42322189e-01, + 3.91511449e-01, 8.67368474e-01, 8.26312958e-01, 7.63415700e-01, + 2.58686841e-01, 9.01702644e-01, 9.04908731e-01, 4.82065073e-01, + 1.03740180e-01, 8.06393032e-01, 4.96334360e-01, 8.66705044e-01, + 8.41035301e-01, 4.59245421e-01, 7.19638625e-01, 8.14396479e-01, + 5.00324014e-01, 9.92023914e-01, 6.85847807e-01, 4.27823386e-01, + 9.80807153e-01, 1.84865464e-01, 5.22785893e-01, 8.68816197e-02, + 5.11839974e-01, 5.59566739e-01, 7.45268286e-02, 6.48721621e-03, + 3.12850372e-01, 9.98760486e-01, 7.91749218e-01, 8.56771435e-01, + 1.28139487e-01, 1.55746956e-01, 9.38488406e-01, 7.83873607e-01, + 1.70765544e-01, 3.92917094e-01, 7.86478733e-02, 9.39939963e-01, + 4.04823396e-01, 9.63631826e-01, 2.33684171e-01, 1.45599454e-01, + 8.42988117e-01, 7.06669576e-01, 6.13829681e-01, 8.94624130e-01, + 2.65020774e-02, 2.06745718e-01, 7.28843723e-01, 3.96858772e-01, + 7.10437357e-01, 4.28819478e-01, 6.90097008e-01, 2.93836406e-01, + 4.40132561e-01, 3.96220698e-01, 1.06889738e-01, 6.64587351e-01, + 5.06934655e-01, 8.93421184e-01, 5.63637256e-01, 6.50586965e-01, + 4.32608624e-03, 3.36838073e-01, 8.60998960e-01, 2.69122592e-01, + 5.76901464e-01, 2.62489938e-01, 2.54987131e-03, 8.12978251e-01, + 2.68082894e-01, 1.63100920e-01, 5.74022218e-01, 6.41915267e-01, + 8.51314008e-01, 2.26402162e-02, 4.16961267e-01, 4.48483938e-01, + 3.52232294e-01, 9.02376305e-01, 8.96245403e-01, 3.15139031e-01, + 1.46404487e-01, 6.52764635e-01, 4.98410494e-01, 6.06476931e-01, + 6.43849062e-01, 9.53659512e-01, 8.29986765e-01, 9.36170797e-01, + 3.99348041e-01, 8.26256061e-01, 6.52409968e-01, 8.49345512e-01, + 9.05091417e-01, 3.96178917e-01, 1.90226900e-01, 4.90332203e-01, + 7.42068655e-01, 7.20034853e-01, 6.01824133e-01, 1.81833343e-01, + 7.42155490e-02, 6.85603289e-01, 6.47746988e-01, 5.52852451e-02, + 6.93039797e-01, 8.69586716e-01, 1.56173534e-01, 5.95549419e-01, + 3.41971782e-01, 2.26118015e-01, 1.34416933e-01, 8.09101198e-01, + 5.19329091e-01, 4.98251539e-01, 4.63284263e-01, 6.16748471e-01, + 1.39761723e-01, 3.60230928e-01, 6.25383043e-01, 8.39903117e-01, + 4.65301339e-03, 2.28299203e-01, 7.39651978e-01, 9.91730454e-01, + 1.09900127e-01, 6.58900635e-01, 9.11180110e-01, 3.72570172e-01, + 6.81599913e-01, 2.42758234e-01, 2.91759271e-01, 5.92133206e-01, + 2.51286527e-01, 6.26639818e-01, 6.61266604e-01, 9.38243714e-01, + 9.60017718e-01, 1.38758457e-01, 4.15637748e-01, 6.72614742e-01, + 9.57904387e-01, 9.48748760e-01, 1.71827837e-02, 1.11286643e-01, + 3.15264587e-01, 6.85756201e-01, 4.64689208e-01, 5.13260994e-01, + 6.55387332e-01, 1.90404579e-01, 8.00139451e-01, 3.00409874e-01, + 5.58878597e-01, 2.22624662e-01, 7.11959889e-02, 6.87531604e-01, + 7.06438026e-01, 9.70894668e-01, 9.36524819e-01, 4.33739916e-01, + 8.31902301e-01, 8.36172919e-01, 1.12783165e-01, 6.24975369e-01, + 7.14322210e-01, 1.82658851e-01, 1.13706381e-01, 5.96102043e-01, + 5.71046353e-01, 3.56880754e-02, 4.48309707e-01, 6.91587382e-01, + 1.35182425e-01, 9.22093091e-01, 6.98601630e-01, 8.71729365e-02, + 2.50610802e-01, 6.38924483e-01, 1.86582009e-01, 2.86284233e-01, + 7.23340048e-01, 4.23655245e-01, 7.45452670e-01, 1.50961783e-02, + 1.43868777e-02, 2.07912741e-02, 3.94027111e-01, 6.47843293e-01, + 2.26814780e-01, 6.55875964e-01, 5.32974120e-01, 2.75195311e-01, + 5.07378427e-01, 3.73241830e-01, 3.18936516e-01, 5.98220468e-01, + 5.93092306e-01, 8.09475495e-01, 4.32731482e-01, 5.87426294e-01, + 7.80897153e-01, 5.31074731e-01, 5.18550755e-01, 4.05415035e-01, + 4.75867532e-01, 7.73422452e-01, 5.79042614e-01, 9.04150829e-01, + 2.67491670e-01, 8.23507152e-01, 8.08249116e-01, 7.77469197e-01, + 7.77529212e-01, 1.72246226e-01, 7.67460799e-01, 4.02734542e-01, + 2.73710767e-01, 4.71453579e-01, 5.69932677e-01, 8.92723487e-01, + 4.30959730e-01, 4.02839086e-01, 4.09902108e-02, 6.02722671e-01, + 5.92897409e-01, 4.43426279e-02, 7.31285595e-01, 7.17330356e-01, + 3.53106544e-01, 1.79783435e-01, 8.79670838e-01, 5.12861702e-01, + 6.61813435e-01, 6.42140967e-01, 6.09253614e-01, 5.00121046e-01, + 3.32729381e-01, 9.92718493e-01, 9.23990928e-01, 1.75163289e-01, + 2.40720996e-01, 4.11267054e-01, 9.78038996e-01, 1.30053190e-01, + 3.46751261e-01, 7.28563708e-01, 6.99494900e-01, 2.94433035e-01, + 1.15144256e-01, 6.93726407e-04, 3.18530826e-01, 6.01677485e-01, + 7.97612355e-01, 8.72316786e-01, 5.20291828e-01, 4.99290831e-01, + 5.70823182e-02, 9.22153637e-01, 4.90522698e-01, 9.74276273e-02, + 7.98290462e-02, 8.70595211e-01, 4.10726019e-01, 7.52595908e-01, + 4.35924653e-01, 2.65245854e-01, 5.89498790e-01, 4.03024022e-01, + 9.05063092e-01, 6.58875081e-01, 4.57839861e-01, 8.49476738e-01, + 8.67706721e-01, 9.63146401e-01, 8.20582789e-01, 8.61768492e-01, + 4.13925448e-01, 3.47244472e-02, 6.50800903e-01, 5.65590195e-01, + 1.13640789e-01, 6.27489991e-01, 2.14319671e-01, 6.52087982e-01, + 2.22071566e-01, 5.76874407e-01, 1.82464938e-01, 9.18942763e-01, + 1.40479690e-02, 6.66479302e-01, 2.50660160e-01, 3.82100787e-01, + 8.38799846e-03, 7.06090941e-01, 3.34950083e-01, 3.53977522e-01, + 6.87152459e-01, 8.53360880e-02, 5.23940945e-01, 4.47105021e-02, + 7.26347519e-01, 4.01460539e-01, 3.98645845e-02, 1.34938348e-01, + 9.84858690e-01, 6.90798927e-01, 8.45220242e-01, 2.40055231e-01, + 7.17003140e-01, 4.78686180e-01, 8.11464420e-01, 3.96921628e-01, + 8.42381350e-01, 7.83277811e-01, 8.26923982e-01, 1.52482944e-01, + 6.46357627e-01, 8.13412855e-01, 6.19059315e-01, 2.16781326e-01, + 8.93422041e-01, 8.23973622e-01, 7.27752196e-01, 3.21930540e-01, + 6.17739245e-01, 2.86744482e-01, 7.62810746e-01, 6.16176876e-01, + 5.34506182e-02, 2.56641000e-01, 4.62871351e-01, 9.01510093e-02, + 5.54161033e-01, 5.36226827e-01, 3.29524889e-01, 5.67120678e-01, + 1.68729553e-01, 6.03179243e-01, 2.63268982e-01, 5.99452285e-01, + 4.73746174e-02, 3.31660338e-01, 7.90031189e-01, 8.51962590e-01, + 5.42750770e-02, 6.49115583e-02, 1.16106045e-01, 8.62547538e-01, + 4.87380008e-01, 9.91667455e-01, 5.49058431e-02, 6.56743598e-01, + 3.52146483e-01, 1.96582821e-01, 8.70906396e-01, 9.43439930e-01, + 6.20690320e-01, 8.13905835e-01, 5.99777143e-02, 8.07295628e-01, + 6.98585463e-01, 6.55295416e-01, 1.79335565e-02, 8.66528575e-01, + 7.95448787e-01, 2.25760695e-01, 6.94883365e-01, 9.04899709e-02, + 2.75857039e-01, 1.47161028e-01, 8.15856204e-01, 4.57271280e-01, + 2.95413290e-01, 7.19273162e-01, 9.40014496e-01, 1.32948359e-02, + 8.57128881e-01, 8.66565562e-01, 2.54646785e-01, 8.23004534e-01, + 2.47711346e-01, 6.15561070e-01, 7.86174065e-01, 3.69029737e-01, + 3.71685156e-01, 9.26807357e-01, 5.62044299e-01, 9.24537106e-01, + 1.35524199e-01, 4.07331428e-01, 7.33903613e-02, 2.77728962e-01, + 8.28676221e-01, 3.58925509e-02, 7.23369346e-01, 7.96285963e-01, + 3.92078280e-01, 7.98968267e-02, 4.36683114e-01, 2.27817009e-01, + 1.51712739e-01, 9.57798208e-01, 4.31912959e-01, 7.11489092e-01, + 8.53141123e-01, 3.78735149e-01, 6.41407298e-01, 6.19329379e-01, + 5.03432538e-01, 1.07157313e-01, 7.47780087e-02, 6.09398498e-02, + 9.71694060e-02, 3.10061383e-01, 1.68850018e-01, 6.44025987e-01, + 2.25634210e-01, 7.18376867e-01, 4.33708643e-01, 5.13621857e-02, + 6.16812142e-01, 3.98266620e-01, 9.64984922e-01, 1.09613995e-01, + 9.58991350e-01, 4.56004266e-01, 1.32965923e-01, 5.86888514e-01, + 7.48678592e-01, 2.19005065e-01, 3.56717472e-01, 7.70376136e-04, + 7.07378863e-01, 2.23984814e-02, 7.87092117e-01, 1.96659228e-01, + 4.57087727e-01, 6.87352114e-01, 2.19573622e-01, 5.49523635e-01, + 8.11984182e-01, 8.14483356e-01, 8.40953324e-01, 2.31454815e-01, + 2.78947927e-01, 2.78532957e-01, 7.10040268e-01, 8.30253191e-01, + 2.99209924e-01, 8.25882477e-01, 5.81379113e-01, 4.25770940e-01, + 8.06465501e-01, 7.50395996e-01, 1.18149115e-01, 2.91278649e-01, + 1.89798539e-01, 1.72768577e-01, 3.60267108e-02, 2.36939560e-01, + 7.96462944e-01, 6.64851749e-01, 4.06920400e-01, 1.24022211e-01, + 2.14890418e-01, 2.86479104e-01, 9.38359711e-01, 2.66248338e-01, + 3.14441258e-01, 4.33500099e-01, 8.21670967e-01, 3.50262912e-01, + 2.04668675e-02, 3.15114998e-01, 9.35173352e-01, 1.20688242e-01, + 9.02704706e-01, 4.44179968e-01, 1.62498781e-01, 8.24454688e-01, + 2.45545919e-01, 1.59717687e-01, 5.78075551e-01, 1.09240697e-01, + 3.33500682e-01, 2.54720295e-02, 1.24460080e-01, 3.65858791e-01, + 3.81253425e-01, 5.75265921e-01, 2.41440154e-01, 9.31528781e-01, + 2.61488038e-01, 4.55649167e-02, 7.79076636e-01, 8.90405817e-01, + 8.57219388e-01, 5.19888211e-01, 2.52734597e-01, 2.95547886e-02, + 6.65540312e-01, 8.53412324e-01, 8.73143550e-01, 9.34336646e-01, + 8.76177549e-01, 6.06182354e-01, 1.87905206e-01, 7.77081995e-01, + 7.94047446e-01, 9.59312088e-01, 4.26727654e-01, 7.50592762e-01, + 2.84645729e-01, 3.13015951e-01, 2.35860393e-01, 3.36604974e-01, + 6.18830577e-01, 5.60224026e-01, 6.91123848e-01, 8.83730449e-01, + 3.08063944e-02, 2.00897430e-01, 7.92166250e-01, 4.62901075e-01, + 8.34055002e-01, 1.97822223e-01, 9.12072314e-01, 4.30890577e-01, + 4.10218302e-01, 4.67830747e-01, 5.13951081e-03, 5.06239755e-01, + 2.84006807e-01, 3.30818338e-01, 7.04589489e-01, 5.08295792e-01, + 3.66481532e-01, 4.15192062e-01, 9.11199460e-01, 8.03988404e-01, + 6.51728248e-01, 9.77564881e-01, 2.55171224e-01, 1.44861629e-01, + 9.45601776e-01, 9.69918541e-01, 5.65384668e-01, 8.07950482e-02, + 3.93608002e-03, 8.99411813e-01, 5.83092071e-01, 9.12930438e-01, + 3.71436091e-01, 3.72860089e-01, 4.63617045e-01, 2.64695052e-01, + 9.57153104e-01, 7.43478360e-01, 2.71932076e-01, 6.36119597e-01, + 7.06178272e-01, 1.72359802e-01, 5.21867902e-01, 4.14521502e-01, + 3.54719483e-01, 1.68309128e-01, 8.55739507e-01, 6.77478610e-01, + 8.17654590e-02, 5.22710842e-01, 8.44737984e-01, 8.69571251e-01, + 8.75292234e-01, 9.80920051e-01, 1.80551918e-01, 5.40994128e-01, + 5.32648563e-01, 3.00903740e-02, 7.70135893e-01, 9.06214482e-01, + 3.99306651e-01, 3.41822929e-01, 9.04735490e-01, 5.49568872e-01, + 4.17715366e-01, 3.13710968e-01, 1.61705444e-01, 7.24025164e-01, + 5.01121517e-01, 8.01219341e-01, 1.53910240e-01, 2.99403630e-01, + 7.08788284e-01, 5.64309033e-01, 4.97339915e-01, 3.57959876e-01, + 7.83259879e-01, 3.38291492e-01, 1.47240714e-01, 9.43943730e-01, + 8.50315041e-01, 7.67558546e-01, 9.47200891e-01, 2.93793939e-01, + 2.94060144e-01, 9.97988891e-01, 8.42805794e-01, 1.44095859e-01, + 9.39273174e-01, 2.11441062e-01, 7.71253610e-01, 3.95114614e-01, + 5.03108637e-02, 2.82149324e-01, 9.44608677e-01, 6.09752464e-01, + 7.08546698e-01, 6.97337208e-01, 6.94653682e-01, 8.78376350e-01, + 1.95380091e-01, 5.08193561e-01, 8.79038037e-01, 3.08200472e-01, + 4.78457359e-01, 4.37728198e-01, 2.11784455e-01, 4.76265202e-01, + 6.51236233e-01, 6.72173626e-02, 5.78136033e-01, 5.88263347e-01, + 7.75432270e-01, 1.05802542e-01, 3.44473911e-01, 2.35196170e-01, + 1.04339004e-01, 6.81826438e-01, 6.32694726e-02, 1.54430645e-01, + 8.17967462e-01, 4.90666673e-01, 4.06443180e-01, 9.75676332e-01, + 3.71438259e-01, 7.59444843e-02, 9.62782532e-01, 1.27783244e-01, + 8.65498744e-01, 9.87630640e-01, 3.50645096e-01, 2.01057201e-01, + 9.78856260e-01, 9.36097695e-01, 5.90743408e-01, 8.36568198e-02, + 9.56506298e-01, 5.44310183e-01, 4.73459002e-01, 7.97335105e-01, + 9.68370787e-01, 5.97292298e-01, 5.32022558e-01, 5.15198787e-01, + 6.48835202e-02, 4.21703557e-01, 2.67196159e-01, 3.35475351e-01, + 2.00120831e-01, 3.79852128e-01, 8.93303729e-01, 1.57907903e-01, + 1.27314971e-01, 4.99153754e-01, 5.46169883e-01, 3.97852611e-01, + 7.74234552e-01, 6.86181238e-01, 5.92067547e-01, 2.13976671e-01, + 3.57346244e-01, 1.26608839e-01, 4.79637984e-01, 6.06959580e-01, + 8.42021307e-01, 2.73088038e-01, 2.59736264e-01, 5.97240469e-01, + 7.56535007e-01, 5.03662794e-01, 4.54303003e-01, 4.54209500e-01, + 9.98163283e-01, 6.79845235e-01, 4.66081937e-01, 5.30574321e-01, + 7.89516493e-01, 2.14929347e-01, 5.30881721e-01, 2.29671115e-01, + 4.40878726e-01, 5.16183706e-01, 7.18662096e-01, 7.41166660e-01, + 2.25848031e-01, 6.22182244e-01, 8.30108206e-01, 2.91599945e-01, + 6.38300120e-01, 3.27744620e-02, 1.31241405e-01, 7.41345648e-01, + 5.23126125e-01, 7.21240929e-01, 6.49794993e-01, 4.49875268e-01, + 2.17249622e-01, 2.96302227e-01, 4.98081638e-01, 1.00481368e-01, + 1.80071913e-01, 2.57772697e-01, 2.48911947e-01, 4.74891198e-01, + 9.13604032e-02, 3.86341099e-01, 2.65009566e-01, 5.56396603e-01, + 2.26041119e-01, 2.06620400e-01, 2.54210154e-02, 6.01557575e-01, + 3.16068190e-01, 2.56070796e-01, 2.91399995e-01, 8.13237606e-01, + 7.28457314e-01, 1.69092225e-01, 4.47953174e-02, 7.21206133e-01, + 4.57683763e-01, 4.12995321e-01, 1.70304098e-01, 8.82111991e-01, + 1.16086028e-01, 9.72298671e-01, 4.15413491e-01, 4.59158446e-01, + 2.76205668e-02, 8.58813445e-01, 1.30998083e-01, 2.46251335e-01, + 4.30752133e-02, 5.75952486e-02, 5.87763021e-01, 5.51387173e-01, + 9.58273129e-01, 6.32428023e-01, 6.21945101e-01, 8.51680344e-01, + 9.86730184e-01, 5.59471038e-01, 7.28549450e-02, 1.32624270e-01, + 2.89986946e-01, 8.78814765e-01, 6.81090440e-01, 1.27247254e-01, + 9.20827861e-01, 8.92096743e-01, 2.13786647e-01, 9.15466928e-02, + 5.84119122e-01, 3.63358390e-01, 4.36501249e-01, 3.80860682e-01, + 9.04810017e-01, 3.93371696e-02, 3.92564829e-01, 6.78766045e-01, + 3.43966776e-01, 1.40013844e-02, 8.35446088e-01, 2.99624041e-01, + 5.40855478e-01, 7.09795470e-01, 2.95056458e-01, 1.68499069e-01, + 5.21405167e-01, 4.89000157e-02, 5.36086729e-01, 1.94189685e-01, + 1.91137583e-01, 8.72211181e-01, 9.75342603e-01, 5.62204790e-01, + 2.40590898e-01, 9.34409629e-02, 3.35948017e-01, 5.36830619e-01, + 7.78632734e-01, 8.49227239e-01, 7.29960539e-01, 9.25858936e-01, + 6.86792213e-01, 2.57330211e-02, 6.73464822e-01, 9.20451112e-02, + 7.48991259e-01, 2.63769336e-01, 9.04201533e-01, 3.41507439e-01, + 8.29063390e-02, 9.12740235e-01, 9.44873474e-01, 6.52539431e-01, + 5.84702825e-02, 7.72132232e-01, 4.83548547e-01, 4.78145422e-01, + 3.43788218e-01, 9.81665739e-02, 4.69355255e-01, 4.61421354e-01, + 4.33676613e-01, 5.92252267e-01, 1.66725150e-01, 1.42115710e-02, + 3.64864896e-01, 2.89136999e-01, 7.79742108e-01, 9.71816674e-01, + 3.00190426e-01, 6.12281938e-01, 3.97577553e-01, 3.68165281e-01, + 4.46587312e-02, 7.01571977e-01, 4.06758097e-01, 6.44809109e-01, + 8.03909756e-01, 1.85778263e-01, 5.98382141e-01, 9.00174123e-01, + 2.86789045e-01, 6.63768777e-01, 2.86744638e-02, 3.06127946e-01, + 1.04728939e-01, 3.92302773e-02, 4.99797957e-01, 4.92956778e-01, + 1.05184878e-01, 2.91791616e-01, 3.12224671e-01, 8.46566754e-01, + 7.75013707e-01, 9.39070916e-01, 2.05915592e-01, 7.30897045e-01, + 7.27113833e-01, 2.93886565e-02, 2.99872224e-01, 2.75341097e-01, + 5.52144238e-01, 3.07481568e-01, 5.23792167e-01, 9.66228012e-02, + 8.49650067e-01, 3.79934821e-01, 9.30389764e-01, 9.84831894e-01, + 6.42343931e-01, 6.97611434e-01, 5.83350063e-01, 6.88610584e-01, + 5.77306162e-01, 3.67916572e-01, 2.50165214e-01, 5.12377327e-01, + 8.19027386e-01, 3.32637100e-01, 8.36917368e-01, 8.26537522e-01, + 1.54941575e-01, 4.61731515e-01, 5.20444401e-02, 1.62627427e-01, + 9.35232397e-01, 2.56387389e-01, 1.49757552e-01, 4.60006427e-01, + 1.97147987e-01, 8.57012838e-01, 9.80435141e-01, 3.03395261e-01, + 9.18672759e-02, 7.25840396e-01, 6.61295266e-01, 9.20092348e-02, + 9.07829336e-01, 4.45778564e-01, 2.24167711e-02, 3.88048710e-01, + 7.38708671e-01, 4.90069797e-01, 4.50536793e-01, 9.28350198e-01, + 6.66497382e-01, 1.10673639e-01, 2.95684591e-01, 2.64281339e-03, + 8.94414913e-01, 5.79935459e-01, 5.68542757e-01, 3.23272744e-01, + 8.76191781e-01, 2.50696551e-01, 5.48297475e-01, 6.42798572e-01, + 4.45587812e-01, 1.26885546e-01, 9.82168265e-01, 4.99123036e-01, + 8.29585102e-01, 2.16470117e-01, 6.61870790e-01, 5.01013865e-01, + 1.41935726e-01, 6.03628336e-01, 8.82142165e-02, 4.78199237e-01, + 3.40033037e-01, 1.65990221e-01, 9.70489072e-02, 5.30353065e-01, + 8.16816576e-01, 5.65825329e-01, 3.83517399e-01, 3.77309615e-01, + 3.97097266e-02, 6.28892651e-01, 2.12768506e-01, 8.53513250e-01, + 5.40896585e-01, 8.83523556e-01, 9.23658221e-01, 2.73542774e-01, + 8.94399286e-01, 8.38876783e-01, 7.70029834e-01, 9.08151992e-01, + 6.49728255e-02, 3.93770462e-02, 6.10108759e-01, 3.57220979e-01, + 8.07951886e-01, 4.73599445e-01, 6.95481583e-01, 1.44957699e-01, + 6.99887460e-01, 3.86235814e-01, 3.27318645e-02, 6.38764496e-01, + 9.25341875e-01, 3.16482354e-01, 1.05084029e-01, 2.60832353e-01, + 9.38619893e-01, 6.65865187e-01, 5.54712475e-01, 6.40106319e-01, + 1.97921823e-01, 7.44039621e-01, 6.07216315e-02, 6.41884028e-01, + 4.35102032e-01, 9.11106397e-01, 2.50588312e-02, 8.82784921e-01, + 9.07660615e-01, 1.12421168e-01, 2.85785527e-01, 7.53092562e-01, + 8.67722134e-01, 1.77992791e-01, 8.86101977e-01, 7.23131731e-01, + 7.55194824e-01, 2.16715237e-01, 1.80614382e-02, 4.66866697e-02, + 2.87435942e-01, 9.66480285e-01, 2.00927646e-01, 5.38945564e-01, + 4.80477321e-01, 3.14560444e-01, 2.14885782e-01, 3.25387687e-01, + 2.61608590e-01, 3.02017086e-01, 7.79909811e-01, 5.63452147e-01, + 3.59273858e-01, 9.36159171e-01, 1.03753034e-01, 3.66360501e-01, + 7.93926004e-01, 8.71701388e-01, 3.52629018e-01, 6.48416964e-01, + 4.91614388e-01, 4.70602494e-02, 6.72923307e-01, 5.30716631e-01, + 7.18770207e-01, 1.85149178e-01, 2.17639128e-01, 8.04818215e-01, + 9.98571564e-01, 3.08143259e-01, 3.36437181e-02, 5.53807556e-01, + 1.57458763e-01, 8.82609910e-01, 1.37909232e-02, 1.54247552e-01, + 6.01978996e-01, 4.13324239e-01, 1.83160784e-01, 7.77498873e-01, + 7.69972836e-01, 2.80718639e-01, 8.67750144e-01, 7.45372160e-01, + 5.17538648e-02, 7.98899230e-03, 9.43646439e-01, 5.04539071e-01, + 4.22340933e-01, 6.47224843e-01, 7.90390038e-01, 8.03536527e-01, + 6.59696029e-01, 8.53998204e-01, 2.43210904e-01, 6.71668693e-01, + 7.49375053e-02, 8.46519701e-01, 3.06491907e-02, 9.08189570e-01, + 3.64337923e-03, 9.55893813e-01, 6.98856097e-01, 8.12786496e-02, + 9.02132505e-01, 6.68469737e-01, 3.20848151e-01, 5.89661413e-01, + 3.85233532e-01, 7.58205297e-01, 8.82752853e-01, 4.98135073e-01, + 5.77447572e-01, 4.95788529e-01, 2.93822011e-01, 9.43635846e-01, + 2.34578907e-01, 1.64977369e-01, 4.90752169e-01, 6.27390300e-01, + 8.28991623e-01, 3.94846864e-01, 8.15233085e-01, 8.23697605e-01, + 5.41586080e-01, 6.79174489e-01, 2.27858081e-01, 1.08760915e-01, + 1.34133051e-03, 8.96360225e-02, 8.36224039e-01, 9.90714290e-01, + 5.58233066e-01, 2.90486840e-01, 3.00546337e-01, 7.42076199e-01, + 5.39029892e-01, 2.89840177e-01, 8.05718119e-01, 8.69912133e-01, + 6.92285486e-01, 7.34000342e-01, 5.94043756e-01, 1.46455220e-01, + 2.27343369e-01, 7.51514005e-01, 4.82879364e-02, 5.44419032e-01, + 9.85279914e-01, 2.81725016e-01, 8.41378605e-01, 9.65722155e-01, + 1.61083824e-01, 5.25033651e-01, 5.05583877e-01, 4.16334845e-01, + 4.14554379e-03, 4.97526373e-01, 8.22099480e-01, 8.21694881e-01, + 3.18252021e-01, 7.01441227e-01, 8.36172415e-01, 4.11720221e-01, + 1.28072502e-01, 6.24153675e-01, 6.37053014e-01, 3.74140377e-01, + 3.53752899e-01, 1.65317357e-01, 2.59173731e-01, 1.66553128e-01, + 2.52968461e-01, 9.55955395e-01, 2.28898534e-02, 6.22315794e-01, + 5.38891667e-02, 1.48180473e-01, 1.37973802e-01, 2.60853184e-01, + 8.43885067e-01, 7.72693953e-01, 2.67544307e-01, 1.24772775e-01, + 7.57828743e-01, 6.84671309e-01, 6.51416717e-01, 2.25225476e-01, + 5.99644998e-01, 6.23742940e-01, 4.65226860e-01, 7.42617559e-02, + 3.18807812e-01, 2.06616165e-01, 3.13234436e-01, 4.99518636e-01, + 1.67451459e-01, 7.45857271e-01, 3.12715793e-03, 2.55550479e-01, + 6.64680763e-01, 2.28871803e-01, 1.19109926e-01, 7.15723241e-01, + 9.60899663e-01, 9.19424722e-01, 5.21271098e-01, 3.44684774e-01, + 1.53259682e-01, 6.65628388e-01, 5.64016364e-01, 2.87863592e-01, + 9.32114634e-01, 3.72907079e-01, 2.59975286e-01, 2.20528399e-01, + 8.12307869e-01, 6.58696392e-01, 3.36726003e-02, 8.56292742e-01, + 3.30377051e-01, 1.15037016e-01, 3.05257404e-01, 8.15835231e-01, + 3.86912880e-01, 2.07869664e-01, 3.02098405e-01, 2.14780850e-01, + 5.33371352e-01, 2.47428352e-01, 7.18541981e-01, 4.99539269e-01, + 7.02894191e-01, 1.27824356e-02, 8.65178573e-01, 4.17767510e-01, + 8.47283685e-02, 9.26811574e-01, 4.70911192e-01, 6.53744614e-01, + 9.22223548e-01, 5.50378286e-01, 1.63336084e-01, 9.01243669e-01, + 5.33367769e-01, 1.33025745e-01, 7.24672708e-01, 9.26677761e-01, + 1.37741741e-01, 2.53674145e-01, 4.43532913e-01, 6.04275393e-01, + 8.10980498e-01, 3.01951089e-01, 5.71606807e-01, 4.60884411e-01, + 5.38174553e-01, 6.94037776e-01, 2.86668498e-02, 4.39302545e-01, + 8.80537506e-01, 1.03847589e-01, 6.91025662e-01, 5.39867949e-02, + 7.43812130e-01, 3.41867079e-01, 3.53884194e-01, 5.01176917e-01, + 2.41966124e-01, 8.63479192e-01, 5.12188305e-01, 9.62652290e-01, + 3.02663973e-01, 3.79710389e-01, 1.93096999e-01, 2.98392804e-01, + 6.65158415e-01, 2.30257025e-01, 2.32254475e-01, 6.30773700e-01, + 8.71043119e-01, 5.03747937e-01, 6.47165299e-01, 2.55509290e-01, + 6.26277610e-01, 6.84436254e-01, 6.61327462e-01, 5.19344809e-01, + 7.27386236e-01, 8.50418451e-01, 6.11660587e-01, 3.52985340e-01, + 2.55853355e-01, 6.18034771e-02, 8.81176575e-01, 7.62725355e-01, + 4.67846046e-02, 6.77907529e-01, 3.93293288e-01, 7.61837331e-01, + 6.00692301e-01, 8.20463128e-01, 4.01810788e-01, 3.92799420e-01, + 6.12399134e-02, 8.03344906e-01, 6.34622453e-01, 4.24438312e-01, + 9.31466256e-01, 8.80238066e-01, 4.37765311e-01, 7.74150877e-01, + 9.24357824e-01, 8.32156740e-01, 6.24222943e-01, 8.41977283e-01, + 9.12118804e-01, 3.09613720e-01, 9.87469304e-01, 2.88164994e-01, + 7.24177660e-01, 8.43235100e-01, 6.22194661e-01, 7.68060813e-01, + 9.77147590e-01, 5.81604755e-02, 8.36563098e-01, 4.61377172e-02, + 5.29668121e-01, 1.34262073e-01, 2.26428603e-02, 1.11809843e-01, + 9.68106178e-01, 9.25664505e-01, 8.77361713e-02, 1.36530070e-01, + 7.21646988e-01, 7.46253478e-01, 1.61322856e-01, 7.95322694e-01, + 1.45165654e-01, 3.58510534e-01, 4.21185727e-01, 5.16769947e-01, + 5.04217360e-01, 2.66574268e-02, 6.95362901e-01, 4.96669465e-01, + 1.20415111e-01, 7.42233024e-01, 7.01889607e-01, 3.30369888e-01, + 5.64318493e-01, 5.19393593e-01, 5.61280112e-01, 1.55156761e-01, + 5.25531465e-03, 4.45086259e-01, 4.46959192e-01, 6.22293459e-01, + 1.95734197e-02, 8.35799147e-01, 4.25423955e-02, 8.52137548e-01, + 9.04683534e-01, 2.08514879e-01, 7.07098565e-01, 7.91235629e-01, + 1.03469753e-01, 7.75504981e-01, 4.52246577e-01, 3.71105177e-01, + 7.63829919e-01, 9.09311995e-01, 4.13256276e-01, 7.19838382e-01, + 2.21534235e-01, 6.44141531e-01, 4.13230490e-01, 1.15878847e-01, + 7.26329167e-01, 9.21542392e-01, 4.71764789e-01, 4.84166337e-01, + 3.26162452e-01, 4.42979530e-01, 9.32492319e-01, 8.51938572e-01, + 5.54384532e-01, 2.90615280e-01, 8.77400798e-01, 8.53221556e-01, + 9.39244576e-01, 6.86344538e-01, 5.32078907e-01, 3.71292846e-01, + 5.30099610e-01, 9.96293913e-02, 1.37968707e-01, 5.37732455e-01, + 6.23351036e-01, 2.56327697e-01, 3.45032389e-01, 5.59168880e-01, + 1.45237793e-01, 1.14495397e-01, 9.76000934e-01, 4.67428646e-01, + 3.37262208e-01, 8.85711733e-01, 7.71257046e-01, 6.71469065e-01, + 3.97974314e-01, 1.30142737e-01, 4.59094357e-01, 7.84232017e-01, + 7.44570471e-01, 1.00520165e-01, 2.91126398e-01, 5.80811428e-01, + 8.98989550e-01, 9.71924608e-01, 6.88992551e-01, 9.58199656e-01, + 8.74014090e-01, 4.24236606e-01, 2.42656461e-01, 4.72488242e-01, + 9.73782147e-01, 2.37262785e-01, 9.61792445e-01, 1.48509803e-01, + 2.11629145e-01, 1.13366955e-01, 1.09012226e-01, 9.12223874e-01, + 1.03901653e-02, 1.75994433e-01, 1.19299892e-01, 4.25802629e-01, + 5.94867245e-01, 6.00679820e-01, 5.57465595e-01, 7.16316815e-01, + 7.96086599e-01, 4.54557691e-01, 9.19541313e-01, 5.19745199e-01, + 6.05278973e-02, 7.50201194e-01, 4.52662154e-02, 7.35166341e-01, + 1.18252067e-01, 9.67366805e-01, 3.68374237e-02, 1.74398383e-01, + 3.22099840e-01, 8.27640568e-02, 3.87862190e-01, 8.39137131e-01, + 9.53222586e-01, 3.68051022e-01, 9.41878539e-01, 2.82101961e-01, + 7.67362236e-01, 3.03702862e-01, 8.96289596e-01, 3.04775114e-01, + 5.88156814e-01, 3.09919097e-01, 4.28924143e-01, 7.15119820e-01, + 7.55110968e-01, 3.70591083e-02, 5.87197607e-01, 7.89893876e-02, + 5.40252492e-01, 8.19258213e-01, 7.65168758e-01, 2.31028033e-01, + 8.06317818e-01, 5.91819389e-01, 6.42716516e-02, 8.60469841e-01, + 5.02692652e-01, 4.72437214e-01, 2.36203583e-01, 7.62296393e-01, + 3.57835411e-01, 7.09380334e-01, 9.65324538e-01, 3.04279042e-01, + 5.77823199e-01, 5.70190089e-01, 4.35061545e-01, 3.67801208e-01, + 3.87011698e-01, 3.02008273e-01, 5.99756399e-01, 2.34647587e-01, + 5.49955533e-01, 4.46487501e-01, 1.29139222e-01, 5.59220781e-01, + 6.65959456e-01, 5.16564037e-01, 6.39020969e-01, 3.59645773e-01, + 2.67237084e-01, 3.92483439e-01, 7.20251303e-01, 8.63001241e-01, + 9.47696551e-01, 7.47728894e-01, 5.97450029e-01, 3.83325258e-01, + 6.04514023e-01, 4.51254363e-01, 8.26276392e-01, 2.62075544e-01, + 2.58475871e-01, 9.51365306e-01, 6.16443482e-01, 9.12852037e-01, + 3.85064508e-01, 5.41813300e-01, 3.50418370e-01, 7.37517327e-01, + 9.59418037e-01, 9.05967968e-01, 7.78601183e-01, 1.93422684e-01, + 6.01139805e-01, 9.47118395e-01, 1.88385509e-01, 3.62670265e-01, + 1.88461219e-01, 9.60773959e-01, 6.41737867e-02, 8.25966168e-01, + 4.26312177e-01, 8.64671182e-01, 3.68261080e-01, 6.52385028e-01, + 9.59641367e-01, 2.79162703e-01, 4.00129018e-02, 5.33289421e-01, + 5.79517144e-01, 4.69888725e-01, 8.62329920e-01, 8.29213446e-04, + 6.23181289e-01, 7.76862703e-01, 5.15074356e-01, 9.79800160e-02, + 1.92022733e-01, 6.05421866e-01, 4.85404683e-01, 1.08325254e-01, + 1.93562428e-01, 4.40610515e-01, 3.55265373e-02, 5.38674463e-01, + 9.06126831e-01, 3.29320226e-01, 6.27469097e-01, 2.85528996e-01, + 2.90995057e-01, 1.26319415e-01, 8.31754971e-01, 6.69290445e-01, + 1.81967153e-01, 8.57700587e-01, 9.53324230e-01, 3.32024211e-01, + 7.97160822e-01, 4.70926704e-01, 4.11445916e-01, 7.42050770e-01, + 8.79718589e-01, 9.23242653e-01, 7.59597129e-01, 4.51272989e-01, + 4.93825407e-01, 3.29752384e-01, 2.17108314e-01, 1.10581369e-01, + 4.57770565e-01, 5.25770748e-01, 4.96270443e-02, 3.46590494e-01, + 8.44889681e-01, 2.04066052e-02, 7.13399695e-01, 7.28892904e-01, + 9.11722119e-01, 7.19418931e-01, 9.38820810e-01, 8.82643881e-01, + 2.50480936e-01, 3.34922661e-01, 1.90869568e-02, 7.10956993e-01, + 1.68187616e-01, 2.92566933e-01, 8.80722338e-01, 2.48884250e-01, + 6.40592462e-01, 3.39448838e-01, 7.21217209e-01, 4.16597600e-01, + 7.48194041e-01, 2.10922462e-01, 3.15319332e-03, 3.55068429e-01, + 8.20362813e-01, 2.53063504e-01, 4.73371736e-01, 2.62233310e-01, + 6.53457288e-01, 8.13231968e-01, 5.44729597e-04, 7.61155354e-01, + 4.17665699e-01, 7.36800580e-02, 5.43074702e-01, 5.44393468e-01, + 5.49567448e-01, 4.15169048e-01, 1.78184367e-01, 8.80828989e-01, + 8.01608004e-01, 8.32633139e-01, 6.04199497e-01, 5.34469505e-01, + 8.14237761e-01, 6.76921805e-01, 6.56300841e-01, 5.14595454e-01, + 9.09174140e-01, 6.84625333e-02, 9.57183750e-01, 6.04097419e-01, + 5.82837816e-01, 7.74836246e-01, 2.44027401e-01, 9.54576179e-01, + 5.31266190e-01, 2.91350470e-01, 5.10250939e-01, 5.62910811e-01, + 9.08124579e-01, 9.54307715e-01, 3.15899550e-02, 9.57302766e-01, + 1.15290745e-01, 3.31393531e-02, 9.97250114e-01, 7.33386478e-01, + 5.48173901e-01, 2.27193248e-01, 1.57753098e-01, 4.41062677e-01, + 9.24626256e-01, 3.34686830e-01, 6.86687926e-01, 8.87207142e-01, + 5.83273451e-02, 2.17598580e-02, 6.70365769e-02, 4.96095197e-01, + 5.46416072e-01, 2.62197529e-01, 5.27047144e-01, 2.70111911e-01, + 8.67426697e-01, 7.93274806e-01, 6.52472851e-01, 7.74711779e-02, + 6.63840539e-01, 6.23164056e-01, 7.96354100e-02, 7.89341247e-01, + 3.67328964e-01, 9.71861742e-01, 1.59700346e-01, 9.32195911e-01, + 1.62680292e-01, 6.19043742e-01, 7.22931729e-01, 7.28505258e-01, + 1.26681205e-01, 8.88981247e-01, 3.27597748e-01, 2.11918105e-01, + 4.53124549e-01, 4.53515422e-01, 5.26377028e-01, 7.95979022e-02, + 1.43994358e-01, 1.72639033e-01, 6.86574596e-01, 2.08833889e-01, + 4.64292165e-01, 2.28840915e-01, 6.44747821e-01, 2.83860723e-01, + 8.96164705e-01, 5.57991439e-01, 3.13723362e-01, 2.86391800e-01, + 5.97732000e-02, 5.77854059e-01, 1.46509010e-01, 6.17127238e-02, + 1.75310735e-01, 3.15108074e-01, 6.37357304e-01, 1.78678284e-01, + 9.68737195e-02, 1.36273898e-02, 3.48571761e-01, 3.86517950e-02, + 8.69163770e-01, 7.74626192e-01, 5.59529291e-01, 5.43916979e-01, + 2.06374565e-01, 5.61446719e-01, 2.28060102e-01, 2.72195059e-02, + 8.09775829e-01, 6.45183218e-02, 7.80265319e-01, 5.81126242e-01, + 1.05437216e-01, 9.82555548e-01, 3.40004880e-01, 7.55473931e-01, + 5.27551267e-01, 7.20772248e-01, 5.16017945e-01, 1.91320457e-01, + 3.99808545e-01, 5.33111934e-01, 4.88030268e-01, 4.31415070e-01, + 2.73758531e-01, 6.18416935e-01, 8.60684714e-01, 6.03515970e-01, + 5.06490523e-01, 9.68396224e-01, 5.94614961e-01, 2.54300061e-01, + 8.42904794e-01, 8.43923209e-01, 7.14167922e-01, 6.13974807e-01, + 5.92883321e-02, 6.90846061e-01, 9.49899961e-01, 6.17620472e-01, + 4.14537612e-01, 6.69297245e-01, 9.23615755e-01, 2.28977224e-01, + 8.41442344e-01, 6.38555273e-01, 5.05087021e-01, 7.45835163e-01, + 1.36977725e-01, 3.39499297e-01, 3.10317820e-01, 1.63572325e-01, + 6.69528006e-01, 2.35521917e-01, 2.81648723e-01, 9.00264371e-01, + 8.07149800e-01, 2.34513733e-01, 4.08127678e-01, 3.37133193e-01, + 6.79799048e-01, 4.17952092e-03, 7.21326725e-01, 5.23310620e-01, + 6.61873846e-01, 9.79183823e-01, 1.56469089e-01, 1.70150086e-01, + 4.11362464e-01, 6.65975294e-01, 9.97119465e-02, 2.07408602e-02, + 1.29615596e-01, 6.29580237e-01, 2.63098622e-03, 6.69340165e-01, + 2.62477123e-01, 5.03887900e-01, 8.15204402e-01, 4.34447491e-01, + 9.60351549e-01, 7.33327700e-01, 1.22530589e-01, 6.87243162e-01, + 8.62927819e-01, 6.12647119e-01, 5.37735304e-01, 7.08919259e-01, + 6.25161420e-02, 9.29647271e-01, 9.78718579e-02, 9.43608886e-01, + 6.77013798e-01, 2.57923383e-01, 2.18889887e-01, 5.41869014e-01, + 3.15095945e-01, 5.85548291e-01, 8.21181213e-02, 6.78003905e-01, + 8.35681922e-01, 2.65473381e-01, 4.07713329e-01, 5.20809763e-02, + 1.13691471e-01, 3.83928998e-01, 9.42417881e-01, 3.13015690e-01, + 7.32306724e-01, 6.97258862e-01, 2.40237433e-02, 7.55086547e-01, + 2.07239310e-01, 1.49344542e-01, 9.67428566e-01, 6.56127380e-01, + 2.82121060e-01, 6.06754076e-01, 9.87513254e-01, 1.01864388e-01, + 9.15830900e-01, 1.13851964e-01, 3.53913901e-01, 6.85123968e-01, + 1.29817387e-01, 3.43314773e-01, 8.32716787e-01, 3.99683297e-01, + 1.36911394e-01, 4.82708400e-01, 9.82539719e-01, 5.23252139e-01, + 6.56238621e-01, 7.25044407e-01, 2.27467943e-01, 2.66302669e-01, + 3.76417429e-01, 8.23316684e-01, 6.65196243e-01, 1.80598271e-01, + 9.91211952e-01, 6.70185150e-01, 9.90687722e-01, 4.15884057e-01, + 9.54460710e-02, 7.78124818e-01, 9.55094568e-01, 3.15561781e-01, + 5.17903148e-01, 4.90402405e-01, 7.03455959e-01, 9.48218682e-02, + 8.46576275e-01, 6.14295388e-01, 3.84444522e-01, 4.43093374e-01, + 8.24536392e-02, 1.62924744e-01, 8.82000785e-01, 7.52974207e-01, + 9.44832231e-01, 1.50927336e-01, 2.13498232e-01, 1.46902912e-01, + 9.17497331e-01, 9.01705963e-01, 5.21162809e-02, 2.89294598e-01, + 1.93457937e-01, 4.52495902e-01, 8.45227779e-01, 6.29748789e-02, + 8.79505835e-01, 1.73411851e-02, 8.60930653e-01, 4.39204654e-01, + 2.60893260e-01, 4.94379715e-01, 2.91115193e-01, 5.75444758e-01, + 2.38248819e-01, 9.92256274e-01, 4.90458918e-01, 1.61784888e-01, + 2.74124457e-01, 2.49226529e-01, 9.29961704e-01, 8.29609286e-01, + 1.11165349e-02, 3.72187970e-01, 3.16178599e-01, 7.91197905e-01, + 1.43127926e-01, 3.78670302e-01, 2.65774420e-01, 1.04441848e-01, + 3.86767239e-01, 8.55258488e-01, 1.64857941e-01, 5.97731844e-01, + 4.51109142e-01, 1.33584542e-01, 6.02753062e-02, 1.29791658e-01, + 1.92910470e-01, 9.64599025e-01, 3.13008773e-01, 3.83875683e-01, + 4.61411653e-01, 4.56330158e-01, 3.16344749e-01, 5.94772183e-01, + 9.98406983e-01, 9.72818293e-01, 7.15445049e-01, 4.37578976e-02, + 2.55096086e-01, 8.51788029e-01, 2.27137283e-01, 8.07410494e-01, + 4.11883527e-01, 8.09334564e-01, 2.91330410e-01, 3.06148260e-01, + 7.80591283e-01, 8.98608108e-01, 2.93627628e-01, 4.33710172e-01, + 5.00386377e-01, 2.83951401e-01, 1.12132167e-01, 9.81444938e-01, + 9.42865888e-01, 7.95462892e-01, 2.00289958e-01, 6.98474943e-01, + 4.84074712e-01, 5.02624245e-01, 1.70857752e-01, 8.34261880e-01, + 4.34606572e-01, 8.21110160e-01, 4.29546752e-01, 6.55869735e-01, + 6.72932563e-02, 5.11468224e-01, 1.83575478e-01, 7.82262752e-01, + 5.54239645e-01, 9.30544690e-01, 5.55978504e-01, 5.94879140e-01, + 3.57362300e-01, 5.51114228e-01, 5.11258693e-01, 5.52578515e-01, + 5.85758455e-01, 4.72205396e-01, 1.89726431e-02, 1.36742917e-01, + 9.77203154e-01, 6.97646853e-01, 9.18953944e-01, 8.26671595e-01, + 3.06945097e-01, 8.92446774e-01, 9.82894499e-01, 8.55807439e-01, + 8.56302056e-01, 7.96966594e-01, 1.33815409e-01, 2.74511784e-01, + 9.45375683e-01, 3.92379873e-01, 1.49454135e-01, 6.51447592e-01, + 3.15268758e-01, 1.11479884e-01, 5.45238749e-01, 1.09171159e-01, + 6.79982053e-01, 9.01266608e-01, 9.99758656e-01, 7.71427341e-01, + 6.34444975e-01, 9.53738456e-02, 5.98671577e-02, 5.83470928e-01, + 4.27922470e-01, 8.58167597e-01, 4.75199107e-01, 1.95104631e-01, + 4.45547585e-01, 1.17368608e-01, 2.47596320e-01, 3.32411043e-01, + 8.57845428e-01, 2.08684864e-01, 7.44072745e-01, 8.34623832e-01, + 4.90542906e-01, 1.83867392e-01, 7.94427073e-01, 6.15143040e-01, + 3.06336995e-01, 6.69799267e-01, 4.19959498e-01, 1.64766311e-01, + 5.27404557e-02, 7.08642104e-01, 1.63948085e-01, 2.87927400e-01, + 7.56459286e-02, 3.92093004e-01, 2.18885020e-01, 4.47518885e-01, + 2.30681052e-02, 5.71202115e-01, 6.08608749e-01, 6.81218143e-01, + 1.75838778e-01, 9.81844587e-01, 3.82605867e-02, 5.26032892e-01, + 5.35347799e-01, 8.24972356e-01, 9.24987993e-01, 3.07283826e-02, + 7.26027195e-01, 4.61810435e-01, 7.25649829e-01, 9.53607051e-01, + 7.65353213e-01, 2.02132537e-02, 6.36697339e-01, 9.13388214e-01, + 9.58224912e-01, 7.15569458e-01, 5.27245300e-01, 7.32816592e-01, + 2.85380475e-01, 3.20896367e-01, 4.47828992e-01, 9.71167817e-01, + 2.56221285e-01, 7.16975666e-01, 6.04449935e-01, 9.49917982e-01, + 6.51284733e-01, 3.65633706e-01, 6.00058987e-01, 9.49061185e-02, + 1.24693991e-01, 1.91570994e-01, 3.60763345e-01, 9.74462161e-01, + 7.77632954e-02, 1.80040975e-01, 6.67094322e-01, 3.52522452e-01, + 7.09100885e-01, 2.88093261e-01, 5.11804998e-01, 8.89625517e-01, + 9.17330680e-01, 7.12463672e-01, 5.50162389e-01, 4.31818119e-01, + 2.24056361e-01, 2.88119290e-01, 3.56105269e-01, 7.05986912e-02, + 2.14221670e-01, 9.70022830e-01, 5.90998284e-01, 2.27749650e-01, + 4.27751989e-01, 8.41296511e-01, 1.44257543e-01, 7.96291711e-01, + 9.63740721e-01, 8.87250707e-01, 6.64631881e-02, 4.28938879e-01, + 7.98835409e-01, 9.23364660e-01, 8.84014902e-01, 6.27148792e-01, + 3.43610001e-01, 1.18396505e-01, 6.98240204e-02, 5.87337658e-01, + 4.12723315e-01, 2.70502573e-01, 7.70901026e-01, 4.15244223e-01, + 3.96870687e-01, 4.46747497e-01, 9.67870645e-01, 6.98832930e-01, + 9.23793996e-02, 9.72109353e-01, 1.60403810e-01, 9.48216758e-01, + 1.36222898e-01, 2.31399441e-01, 6.67547576e-01, 9.83334994e-01, + 5.28334060e-01, 7.64248605e-01, 6.16859186e-01, 7.62079876e-01, + 8.11861122e-02, 3.02162742e-01, 1.15441729e-01, 1.66696316e-01, + 5.08037961e-01, 8.11615380e-01, 4.32724665e-01, 8.76707283e-01, + 3.93076726e-01, 2.51058283e-01, 6.26391713e-01, 9.31200262e-01, + 4.33537763e-01, 5.13680779e-01, 6.08768932e-01, 4.38561208e-02, + 9.17764550e-01, 1.72580098e-01, 6.13626661e-01, 2.94865212e-01, + 9.41809459e-01, 3.80269352e-01, 3.69523633e-01, 2.45993660e-01, + 6.17057731e-01, 2.65016444e-01, 1.97643035e-01, 4.26843955e-02, + 6.31242423e-01, 5.31985633e-01, 7.78806736e-01, 4.06015878e-01, + 9.18073158e-01, 8.44735412e-01, 3.08973440e-01, 4.67886558e-01, + 2.47220207e-01, 1.81057659e-01, 6.89187124e-01, 2.86850870e-01, + 9.04788747e-01, 5.58144105e-02, 4.94954015e-02, 6.19401576e-01, + 9.86786782e-01, 4.43670730e-01, 2.73559613e-01, 4.80374592e-01, + 3.83982467e-01, 8.38094240e-01, 8.52386159e-01, 9.08448741e-01, + 1.27964139e-01, 4.20049817e-01, 6.53669359e-01, 4.76127942e-01, + 5.39329600e-01, 5.72320540e-01, 6.18876778e-01, 9.35410209e-01, + 6.64482253e-01, 5.60225061e-01, 3.74196817e-01, 7.86324500e-01, + 5.00768226e-01, 1.09086678e-01, 8.66148403e-01, 8.81441455e-02, + 4.08932478e-01, 3.29114757e-01, 2.62452676e-01, 8.83542188e-01, + 1.98059204e-01, 6.62082794e-01, 7.54058132e-01, 5.35987562e-01, + 6.10916164e-01, 8.38673148e-01, 9.14514960e-01, 1.59470322e-01, + 7.88226385e-01, 4.49959111e-01, 9.43590263e-02, 8.09634505e-02, + 4.84204320e-01, 1.52631291e-01, 4.24233589e-03, 3.44016214e-01, + 7.10700686e-01, 2.94080244e-02, 2.59189410e-01, 6.65763214e-02, + 5.24802848e-01, 8.05264317e-01, 3.65926335e-01, 3.79386940e-01, + 4.88413725e-02, 2.61042215e-01, 2.47488687e-01, 7.54681056e-01, + 4.71464597e-01, 2.72550270e-01, 9.99652267e-01, 6.85080139e-01, + 3.90135401e-02, 5.65043251e-01, 7.00775614e-02, 7.68480725e-01, + 3.55075682e-01, 6.26231932e-01, 9.35077946e-01, 5.89336892e-01, + 4.81097543e-02, 8.85469637e-01, 2.78013135e-01, 1.45685239e-01, + 9.46063080e-01, 3.56543129e-01, 1.70488453e-01, 1.25744350e-02, + 6.56398149e-02, 3.35308341e-01, 2.63578976e-01, 3.96929542e-02, + 4.68983308e-01, 6.80831739e-01, 7.00756750e-01, 6.37779370e-01, + 4.63898984e-01, 4.22244940e-01, 8.91506008e-01, 7.32244107e-01, + 8.18720906e-02, 8.94706795e-02, 2.66925819e-03, 3.14684697e-02, + 6.20052880e-01, 2.62956329e-01, 4.59523890e-01, 4.29524686e-01, + 5.61467679e-01, 2.37448341e-02, 6.61865564e-01, 2.82557472e-01, + 8.31034031e-01, 6.04689355e-02, 6.89960493e-01, 3.82867236e-01, + 7.25300227e-01, 9.68309449e-01, 6.29340476e-02, 3.57591987e-02, + 9.62638970e-01, 4.95106211e-01, 5.50461455e-01, 3.68302784e-01, + 1.73265281e-01, 4.06005746e-01, 3.75885343e-01, 7.41839872e-01, + 9.79304285e-01, 2.12989371e-01, 3.28154585e-01, 8.00886449e-01, + 3.40491035e-01, 9.37968873e-01, 9.71693077e-01, 3.35094131e-01, + 8.25710953e-01, 8.16638487e-01, 9.23203954e-01, 4.83146249e-02, + 7.63632459e-01, 8.41022301e-01, 9.52121768e-01, 4.20628843e-01, + 7.52257938e-01, 9.62400956e-01, 9.60043951e-01, 3.48746358e-02, + 5.65216728e-01, 4.40061274e-01, 2.05740588e-01, 5.12052016e-01, + 5.34453003e-01, 6.21597163e-01, 6.67527506e-01, 7.70121176e-01, + 6.31012388e-03, 4.75724569e-01, 6.16579919e-01, 1.18153781e-01, + 2.86415676e-01, 4.66663860e-01, 3.81876837e-01, 6.18906168e-01, + 8.73824632e-01, 7.74091439e-01, 9.37880950e-01, 5.09677506e-01, + 7.36384564e-01, 4.18190695e-01, 6.08185066e-01, 8.14176705e-01, + 7.06449728e-01, 6.10095406e-02, 6.08450023e-02, 7.41851696e-02, + 1.28725190e-01, 3.61447933e-01, 5.33970011e-02, 7.94488210e-01, + 9.45183984e-01, 3.20925505e-01, 9.66811962e-01, 6.59801252e-01, + 4.07095049e-01, 1.44426741e-01, 7.74755565e-01, 8.80817116e-01, + 4.10544826e-01, 1.74843735e-01, 3.90229640e-01, 1.85545825e-01, + 4.01208103e-01, 4.57355296e-01, 6.07578701e-01, 6.47966355e-01, + 2.56743210e-01, 6.56804053e-01, 3.32227468e-01, 6.00229815e-01, + 3.47242708e-01, 9.02969445e-01, 3.15309500e-01, 4.55802472e-01, + 7.71695065e-01, 7.98341078e-01, 6.57411720e-01, 1.98758875e-01, + 8.87107134e-01, 8.38011573e-01, 2.78958751e-01, 3.37113898e-01, + 5.97295169e-01, 1.73445095e-01, 1.31042831e-01, 4.18948261e-01, + 4.42501422e-01, 1.62787243e-01, 4.01877271e-01, 9.87490788e-01, + 5.66572768e-01, 5.29382537e-01, 9.97068903e-01, 9.23510397e-01, + 7.65952077e-01, 6.22102808e-02, 1.94407457e-01, 1.88688184e-01, + 5.95841901e-01, 2.90353412e-01, 5.46889956e-01, 2.88063889e-01, + 9.05040559e-01, 7.06262460e-01, 6.45778791e-02, 5.82536706e-01, + 7.37502657e-02, 9.05911173e-01, 2.49948561e-01, 6.32176169e-01, + 3.17138726e-01, 1.74861836e-01, 6.94935150e-01, 9.63148501e-01, + 8.27974967e-01, 1.74496387e-01, 7.80570414e-01, 7.70277644e-01, + 8.21469460e-01, 5.53280119e-01, 4.74679375e-01, 5.63452819e-02, + 3.50204295e-01, 1.09935961e-01, 5.00335043e-01, 4.59518830e-01, + 4.82661944e-01, 7.79635233e-01, 9.11577645e-01, 8.37074271e-01, + 1.06218334e-01, 6.61894523e-01, 8.17504230e-01, 1.01257143e-01, + 1.60481357e-01, 1.02673584e-01, 9.02316584e-01, 6.44972928e-01, + 5.32904638e-02, 8.94438680e-02, 7.36407797e-01, 3.34645367e-01, + 8.20179901e-02, 6.61853604e-01, 2.95691518e-01, 8.58580608e-01, + 6.06943840e-01, 9.64224351e-01, 3.14044471e-01, 3.86852755e-01, + 4.18146382e-03, 2.87528245e-01, 5.15237478e-01, 6.91323944e-01, + 3.90392657e-01, 4.97436300e-02, 9.45388564e-01, 5.41323604e-01, + 9.76321456e-01, 3.61046072e-01, 5.97269496e-01, 5.87112685e-01, + 3.02623055e-01, 4.21488461e-01, 4.61471906e-01, 7.07562855e-01, + 9.76950026e-01, 4.08164489e-01, 1.17914934e-01, 1.59743284e-01, + 5.63966962e-01, 8.56956445e-01, 7.87062706e-01, 1.43730956e-01, + 5.45003941e-01, 2.04064374e-01, 1.16031920e-01, 3.47203102e-01, + 3.62803456e-01, 8.80334329e-01, 2.43595213e-01, 6.74743597e-01, + 1.18138396e-01, 9.50954586e-02, 4.08779476e-01, 8.96756252e-01, + 9.74174738e-01, 7.26373193e-01, 4.63050648e-02, 3.52940713e-01, + 9.38579368e-01, 2.38438009e-01, 9.25880655e-01, 7.98281828e-01, + 1.50950891e-01, 6.18452453e-01, 7.39062939e-01, 2.33972119e-01, + 2.25166326e-01, 1.34080629e-01, 9.15752293e-01, 4.30114261e-01, + 9.74359742e-01, 4.19977877e-01, 7.80747056e-01, 4.96372273e-01, + 2.64323180e-01, 9.77061896e-01, 3.47528219e-01, 9.97990581e-01, + 9.73876292e-02, 7.64051873e-01, 5.42059077e-01, 6.87290372e-03, + 7.03490416e-01, 5.00093339e-02, 2.07963007e-01, 7.01977608e-01, + 9.32281541e-01, 6.74998117e-01, 7.50587832e-02, 2.66057722e-01, + 4.21820451e-01, 3.44778833e-01, 7.47740264e-02, 1.36901833e-01, + 1.04557631e-01, 9.33866576e-01, 8.56143904e-01, 2.54388189e-01, + 4.83347831e-01, 6.10157306e-01, 6.53228002e-01, 5.79304368e-01, + 6.39274961e-02, 9.85907925e-01, 9.81760836e-01, 7.98927862e-01, + 2.21472711e-01, 4.30357966e-01, 1.82336985e-01, 7.18309623e-02, + 4.31570489e-01, 9.27112783e-01, 6.97018225e-02, 2.74141762e-01, + 1.64430290e-01, 2.72405990e-01, 9.39344694e-01, 7.26754788e-01, + 3.55943946e-01, 1.19201333e-01, 4.05683192e-01, 7.76101234e-01, + 5.59559636e-01, 5.69339612e-01, 2.75641508e-01, 6.34215452e-01, + 6.00382636e-01, 1.46210228e-01, 9.41941543e-01, 4.85583573e-01, + 3.74622491e-01, 7.44596714e-01, 6.54545216e-01, 4.20165196e-01, + 5.11594525e-01, 1.37475434e-01, 4.50806509e-01, 6.99882454e-01, + 9.95488724e-01, 6.39245429e-01, 7.50350490e-02, 3.12114831e-01, + 3.47595455e-01, 4.29320733e-01, 5.50589733e-01, 5.34776605e-01, + 4.56549603e-01, 6.31550990e-01, 9.60056330e-01, 9.05569337e-01, + 9.89919133e-01, 9.50830516e-01, 6.89600929e-01, 6.41082819e-01, + 8.07187388e-01, 3.62964645e-01, 3.92638872e-01, 9.13878850e-01, + 3.50776636e-01, 6.76043191e-01, 2.12791066e-01, 3.42245136e-01, + 7.67042252e-01, 3.88472593e-01, 1.63296357e-01, 7.64053078e-01, + 1.75466677e-01, 3.76815779e-01, 9.65846358e-01, 9.55781684e-01, + 4.52065609e-01, 9.55350089e-01, 1.90581373e-01, 7.46196607e-02, + 9.63626146e-01, 3.17247835e-02, 9.07884411e-01, 5.00037485e-01, + 3.03986070e-01, 3.63880030e-01, 9.19447621e-01, 4.00030889e-01, + 8.34088054e-01, 6.13295406e-01, 6.46826177e-01, 3.18945584e-01, + 1.60945497e-01, 3.45782958e-01, 6.92872779e-02, 6.81971054e-01, + 8.19983072e-01, 7.39375905e-01, 4.16506388e-02, 1.18896078e-01, + 3.48979571e-01, 7.73400491e-01, 8.25352926e-01, 1.89126791e-01, + 8.05253340e-01, 6.27346424e-01, 1.91032452e-01, 4.56431152e-01, + 7.07081172e-01, 3.34673953e-01, 2.18900686e-01, 5.06215808e-02, + 4.77174556e-01, 4.36146106e-01, 8.20932455e-01, 5.96163888e-01, + 5.31083479e-01, 9.21358950e-01, 2.93185215e-01, 9.58205287e-01, + 3.20887685e-01, 8.69121760e-01, 7.94031243e-02, 2.07362894e-02, + 6.88503971e-01, 1.73461388e-01, 4.09625305e-02, 1.30144930e-01, + 5.73262464e-01, 9.94783540e-01, 3.41687060e-01, 8.90181528e-01, + 4.32269634e-01, 3.17332715e-01, 9.09746235e-01, 8.94719298e-01, + 9.30473163e-01, 5.37484415e-01, 6.20943067e-01, 3.98758707e-01, + 3.35593149e-02, 1.20211283e-01, 5.90303647e-01, 6.55558929e-02, + 1.11802061e-01, 5.82635576e-01, 5.11702210e-01, 3.12911085e-01, + 7.74801586e-01, 9.49704238e-01, 1.00576454e-01, 1.66847008e-01, + 3.98241342e-01, 6.71887110e-01, 8.54376842e-01, 8.62468560e-01, + 3.04115488e-01, 6.87066152e-01, 7.10335863e-01, 2.37908990e-01, + 7.88544539e-01, 8.07316022e-01, 4.47620475e-01, 9.12845203e-01, + 2.95443529e-01, 1.03519141e-01, 3.46729040e-01, 7.03346617e-01, + 4.83586791e-01, 2.86845230e-01, 4.04984531e-01, 1.87200554e-01, + 3.01758021e-01, 8.41834523e-01, 6.03005083e-01, 3.85012355e-01, + 6.71631379e-01, 3.84784509e-02, 2.83588981e-01, 5.69737771e-01, + 4.54740703e-01, 9.28387202e-01, 4.38227539e-01, 6.71129161e-01, + 2.48419057e-01, 9.86495977e-01, 3.22837329e-01, 7.24915921e-01, + 8.43628445e-01, 6.63838724e-01, 2.56677813e-01, 2.20931776e-01, + 4.41666478e-01, 5.27767851e-02, 2.68927431e-02, 3.49834264e-01, + 5.11565536e-01, 8.80963125e-01, 4.38673079e-01, 8.93248328e-01, + 4.58276188e-01, 1.77053103e-01, 3.71858384e-01, 9.99780376e-01, + 7.80501873e-01, 2.65394139e-01, 2.25218860e-01, 4.42027258e-01, + 3.00543910e-01, 2.79238734e-01, 3.58628815e-01, 8.35333999e-01, + 7.16029244e-02, 3.76915423e-02, 1.80127988e-01, 1.62889643e-02, + 6.02145700e-01, 5.01767023e-01, 8.02582834e-01, 7.44893117e-01, + 2.39221273e-01, 9.92019200e-01, 1.34508613e-01, 3.37111091e-01, + 9.16794821e-01, 3.30985085e-01, 5.58162751e-01, 2.62423639e-01, + 9.82453849e-01, 9.01893007e-01, 5.48791870e-01, 5.72496673e-01, + 9.88055944e-01, 4.16654333e-01, 5.86550574e-01, 1.90380230e-02, + 4.84423367e-01, 3.71512376e-01, 6.81597973e-01, 6.98827854e-01, + 6.87943499e-01, 7.46831351e-01, 1.31785127e-02, 3.40233093e-01, + 1.40710944e-01, 8.64518863e-01, 5.64835915e-01, 7.45310700e-01, + 1.52336418e-01, 9.08736423e-03, 4.59945139e-01, 9.42465539e-02, + 1.12567403e-01, 1.98660782e-01, 6.01430746e-01, 9.06232333e-01, + 4.28312092e-01, 5.27729205e-01, 8.84416814e-03, 2.39647940e-01, + 4.91474715e-01, 6.95213144e-01, 3.77249302e-01, 8.79430787e-01, + 6.34006134e-01, 7.19389691e-01, 8.51835635e-01, 7.78467626e-01, + 1.74993909e-01, 7.90886223e-01, 3.28002963e-02, 5.10988615e-01, + 5.02353376e-01, 7.14365230e-01, 3.53268896e-01, 5.50970666e-01, + 5.81049677e-01, 6.71265418e-01, 1.77240858e-03, 8.68355224e-01, + 1.75909166e-01, 9.58530790e-01, 1.47608939e-01, 7.35674896e-01, + 3.32165079e-01, 2.95203021e-01, 4.06235236e-03, 5.30335365e-01, + 4.68319802e-01, 1.83639665e-01, 3.05326650e-01, 8.16752763e-01, + 4.37674064e-01, 2.42786905e-01, 1.93591813e-01, 1.93503206e-01, + 1.63315947e-01, 8.20632916e-01, 4.02131155e-02, 2.77254521e-01, + 2.29075315e-01, 1.09260118e-01, 3.52436874e-01, 8.55930413e-01, + 2.26078646e-01, 5.00127022e-01, 3.20940961e-01, 5.01200557e-01, + 9.09853426e-01, 7.81909710e-01, 7.89344644e-01, 2.11555966e-01, + 3.05351180e-01, 2.68138024e-01, 7.98352470e-01, 8.58311690e-01, + 1.80452631e-01, 3.19224183e-01, 6.55469263e-01, 7.96099079e-01, + 2.32678360e-01, 8.94487688e-01, 6.47173538e-01, 3.67753864e-01, + 1.40405581e-01, 4.37813857e-01, 3.19217073e-01, 1.38785589e-01, + 8.08768036e-01, 7.96708070e-01, 4.07268132e-01, 1.37554966e-01, + 1.85723372e-01, 1.00201311e-01, 3.87051523e-01, 3.61065129e-01, + 1.71838044e-01, 4.89252468e-01, 5.96842515e-01, 2.71747006e-01, + 1.09541712e-01, 3.48533605e-01, 1.42106437e-01, 4.19123313e-01, + 2.87764859e-02, 6.63468055e-01, 9.91460691e-01, 1.49475978e-01, + 8.31455868e-01, 8.62946210e-02, 1.78712503e-01, 4.45288590e-01, + 2.05984316e-01, 5.05270844e-01, 4.17400416e-02, 2.10584390e-01, + 8.52235054e-02, 3.79741630e-01, 3.47130720e-01, 1.89172952e-01, + 8.29253193e-01, 9.83182113e-01, 6.56200204e-01, 2.40791697e-01, + 8.66918485e-02, 6.62608354e-01, 3.42895904e-01, 3.13135770e-01, + 4.89450311e-01, 9.81945246e-01, 2.24373613e-01, 1.95066894e-01, + 5.31521914e-01, 2.38755730e-01, 8.73314648e-01, 7.38295608e-01, + 1.97668409e-01, 6.29815923e-01, 7.48782414e-01, 4.63727717e-01, + 4.08905145e-01, 1.52806182e-01, 8.64708262e-01, 7.32649119e-01, + 4.92471818e-01, 1.58355632e-01, 4.10387107e-01, 6.74947769e-01, + 6.51081826e-01, 4.40716769e-01, 1.03992746e-01, 7.91779747e-01, + 5.89023279e-01, 1.95508533e-03, 9.58791604e-01, 7.14453423e-02, + 2.65693113e-01, 3.40551770e-01, 2.05525586e-01, 8.88155039e-01, + 4.71269973e-01, 2.69948067e-01, 5.27269508e-01, 5.01994326e-01, + 5.23530428e-01, 9.16343977e-02, 4.82916813e-01, 4.17407263e-01, + 2.30483113e-01, 6.18783139e-01, 3.54866004e-01, 4.32938429e-01, + 5.55163693e-02, 3.18713205e-01, 4.75861140e-01, 9.39934808e-01, + 3.32654562e-04, 9.25126170e-01, 9.17292724e-02, 7.87674904e-01, + 6.45444189e-01, 9.45603844e-01, 7.20766270e-01, 2.49602245e-01, + 2.42740307e-01, 9.45684078e-02, 2.52042007e-01, 4.96740732e-01, + 3.90514803e-01, 7.04841888e-01, 2.28977827e-01, 7.58324849e-01, + 9.56302951e-01, 9.92172185e-01, 3.35505496e-01, 7.31062910e-01, + 2.65275508e-01, 4.85947503e-01, 2.39967130e-01, 6.55884020e-01, + 8.81661084e-01, 9.44992478e-01, 8.15575232e-01, 8.20967518e-01, + 3.63462321e-01, 2.70739059e-01, 7.34649284e-01, 7.84702472e-01, + 5.86517029e-01, 3.48718909e-02, 8.08280907e-01, 7.98705019e-02, + 8.52340877e-01, 1.12333976e-01, 8.69629076e-01, 7.12914602e-01, + 8.77362692e-01, 6.57353647e-01, 2.45196648e-01, 6.81771700e-01, + 4.28040262e-01, 7.24897734e-01, 5.13875315e-01, 5.55731348e-01, + 2.32093533e-01, 3.66129782e-01, 2.46871359e-01, 4.13743295e-01, + 6.81699554e-01, 5.31208366e-01, 4.70497296e-01, 4.12937903e-01, + 3.82364880e-01, 4.67399014e-01, 2.56072172e-01, 8.29287260e-01, + 7.45233038e-01, 5.59245496e-01, 4.60209562e-01, 5.27085126e-01, + 1.79489811e-01, 2.78117901e-01, 3.70673679e-02, 8.10906362e-01, + 4.24150657e-02, 7.21429857e-01, 3.15197341e-01, 6.13853198e-02, + 7.64076244e-01, 4.43850995e-02, 3.42261056e-02, 2.05102034e-01, + 3.29423518e-01, 3.44886444e-01, 6.96171546e-01, 7.67902815e-01, + 2.82685517e-01, 8.87451937e-01, 2.00156099e-01, 4.58022319e-01, + 9.92738656e-01, 1.42457317e-01, 5.24176119e-01, 6.45880600e-01, + 7.02636082e-01, 4.09585698e-01, 4.71450907e-02, 1.61357063e-01, + 1.87931919e-01, 6.17340633e-01, 1.21272058e-01, 8.70088711e-01, + 3.67712200e-02, 7.87877050e-01, 8.09877675e-01, 7.28020115e-01, + 2.58105115e-01, 2.96696599e-01, 1.74100663e-02, 9.13461897e-01, + 9.13327484e-01, 5.31520357e-01, 7.55329909e-01, 1.36846592e-01, + 6.29202192e-01, 6.23276699e-02, 6.20152988e-01, 5.41082187e-01, + 3.80813779e-01, 4.01999700e-01, 6.50019595e-01, 5.39472632e-01, + 8.69135498e-01, 8.22734833e-01, 1.66716737e-01, 7.88198946e-01, + 4.13234600e-01, 9.09346233e-01, 7.54557649e-01, 7.41814281e-01, + 5.70210395e-01, 8.54038442e-01, 3.83804711e-02, 5.22029323e-01, + 9.33984149e-01, 9.40383170e-02, 5.61376332e-01, 7.00904489e-01, + 4.56901588e-01, 1.19418932e-01, 2.12451795e-01, 1.47509627e-01, + 3.86119692e-01, 8.34627498e-01, 4.19214401e-01, 4.09600370e-01, + 4.63936888e-01, 8.68129290e-02, 4.51024183e-01, 7.85286896e-01, + 9.55640011e-01, 6.29081179e-01, 9.01006547e-01, 8.47311890e-01, + 1.93194272e-01, 6.99090093e-01, 3.94260918e-01, 9.09225996e-01, + 7.30348061e-01, 3.60759292e-01, 7.04730102e-01, 7.89231408e-01, + 7.65067412e-01, 5.55551444e-01, 4.74987804e-01, 5.15585983e-01, + 4.99860306e-01, 6.23858200e-01, 9.88767757e-01, 7.59155571e-01, + 7.81156552e-01, 7.09345902e-02, 8.18154306e-01, 4.36901386e-01, + 6.36775360e-01, 7.64778994e-01, 9.13415902e-01, 3.84131791e-01, + 4.05706919e-01, 5.06080682e-01, 1.40408408e-01, 6.08390498e-01, + 7.75143381e-02, 6.09403869e-01, 3.22736094e-02, 9.25164512e-01, + 9.62963785e-01, 5.47097112e-01, 9.75645860e-01, 4.26292446e-01, + 8.37163224e-01, 9.29986616e-01, 3.33631403e-01, 1.24604936e-01, + 8.44057799e-01, 7.65297525e-01, 5.97567375e-01, 3.64837836e-01, + 6.97693392e-01, 1.90614794e-01, 1.14320442e-01, 7.64117228e-01, + 1.57938635e-01, 8.64849288e-02, 8.38951546e-01, 1.16393362e-01, + 3.60523994e-02, 5.18621460e-01, 9.34860501e-01, 5.52268492e-01, + 4.13962508e-01, 8.93529638e-01, 3.53612069e-01, 5.57069292e-01, + 7.11374848e-01, 6.21821983e-01, 3.49795226e-01, 6.22511243e-01, + 8.47361946e-01, 3.06124725e-01, 2.96303659e-01, 5.93372330e-01, + 6.14929754e-02, 2.93878476e-01, 3.89298168e-01, 2.68298736e-01, + 8.70898180e-01, 3.77342326e-01, 9.76330231e-01, 3.40606899e-01, + 9.93538450e-01, 7.69074825e-01, 3.82799165e-01, 8.59370261e-01, + 8.81389769e-01, 2.78814769e-01, 3.75621865e-01, 2.77644505e-01, + 8.92055026e-01, 7.44626111e-01, 3.21168748e-01, 4.60433843e-01, + 1.00546338e-01, 5.62289832e-01, 5.08464387e-01, 6.56255345e-01, + 9.47911969e-01, 6.90855939e-01, 4.78644948e-01, 1.34185684e-01, + 4.30400642e-01, 8.41191330e-01, 4.65513954e-01, 3.50046231e-01, + 2.66173515e-01, 3.56863844e-01, 6.73404912e-01, 3.24343279e-01, + 1.35571167e-01, 7.91268387e-01, 3.39882763e-02, 8.24100191e-02, + 9.44319164e-01, 2.38671559e-01, 2.52321380e-01, 2.81938456e-01, + 6.02851042e-01, 8.68074849e-01, 1.79939176e-01, 5.87776452e-01, + 2.79526963e-01, 8.10512342e-01, 2.30689512e-01, 1.29700840e-01, + 7.16583612e-01, 8.50513097e-01, 9.22311895e-01, 6.57592273e-01, + 9.28874172e-01, 7.43244822e-01, 9.68863925e-02, 6.36000009e-01, + 5.06236072e-01, 9.98243861e-02, 2.04019993e-01, 7.97635869e-01, + 2.74243985e-02, 8.40244762e-01, 3.26961810e-01, 5.77010022e-01, + 3.11169408e-01, 4.10332088e-01, 8.77483092e-01, 2.93716266e-01, + 8.22536238e-01, 3.99455126e-02, 6.70739251e-01, 9.45414350e-01, + 2.24131761e-01, 6.58385601e-01, 3.14792216e-01, 1.42281886e-01, + 9.36157697e-01, 3.73417620e-01, 9.89129857e-01, 5.82213166e-01, + 6.11650836e-01, 9.66779532e-01, 3.87011737e-01, 4.08860754e-01, + 7.94275517e-01, 4.94225320e-01, 7.49977255e-02, 5.97561663e-01, + 9.73264753e-01, 3.43786385e-01, 8.19731176e-01, 1.79011756e-02, + 3.35124754e-01, 4.33870639e-01, 8.49037855e-01, 3.03619782e-01, + 3.30553265e-02, 7.98049298e-01, 7.52795367e-01, 3.16463587e-01, + 2.65180850e-01, 1.12909106e-01, 4.54742492e-01, 9.60433138e-01, + 7.43190883e-01, 9.25185733e-01, 3.55492469e-01, 8.31973385e-01, + 1.93456874e-01, 8.55537061e-01, 7.08145720e-01, 2.65625356e-01, + 5.15945695e-01, 4.98082091e-01, 4.88479507e-01, 6.88269121e-01, + 3.83142787e-01, 4.34293708e-01, 6.65411085e-01, 5.29845249e-01, + 6.10655112e-01, 2.90666547e-01, 5.39064518e-01, 4.18583745e-01, + 9.51910484e-01, 4.67264825e-01, 8.63619911e-01, 1.43812416e-01, + 3.65441883e-01, 1.51903355e-02, 2.91651822e-01, 1.46398723e-01, + 4.26408061e-01, 6.52947680e-01, 5.78798086e-01, 5.62569135e-01, + 5.61162974e-01, 7.01687660e-01, 1.16848091e-01, 2.81601787e-01, + 1.90239966e-02, 7.85435004e-01, 3.69065150e-01, 3.51738794e-01, + 3.92916412e-01, 5.13621859e-01, 3.23188309e-01, 6.03319428e-01, + 3.45303179e-01, 3.08774018e-03, 5.39986636e-01, 8.47477186e-01, + 9.65414852e-01, 1.79164825e-01, 4.44995403e-01, 2.46904669e-01, + 5.13122272e-01, 4.90742951e-01, 1.15099119e-01, 2.87047326e-01, + 4.69629412e-01, 2.97830893e-01, 8.49407377e-01, 6.60486857e-01, + 3.64270079e-02, 5.22093120e-01, 5.22731141e-01, 2.40812380e-01, + 7.22398685e-01, 4.19020099e-01, 8.08851109e-01, 2.25022070e-01, + 5.54232845e-01, 7.53350331e-01, 7.47244253e-01, 9.00042018e-01, + 9.15222228e-01, 4.44562479e-01, 9.64952490e-01, 5.05577907e-01, + 6.86374211e-01, 6.60364564e-01, 8.86718906e-01, 6.46747284e-01, + 4.47963222e-01, 3.84895099e-01, 7.50738725e-01, 3.71259709e-02, + 3.45042053e-01, 9.33599800e-01, 8.06397726e-01, 2.09202761e-02, + 7.93360593e-01, 1.64686557e-01, 7.52163417e-01, 7.27035203e-01, + 1.95849437e-01, 9.33039885e-01, 5.57272389e-01, 9.91927926e-01, + 7.84055433e-01, 1.11178323e-01, 9.49985534e-01, 5.10225195e-01, + 6.85958972e-02, 6.15635484e-01, 4.57068119e-01, 7.26102504e-02, + 7.53839197e-01, 5.30583339e-01, 8.82248410e-01, 6.43368275e-01, + 5.51899777e-01, 1.10580029e-01, 1.74628930e-01, 7.06735629e-01, + 1.26095785e-01, 5.89298206e-01, 2.63810321e-01, 5.67592501e-01, + 9.82917535e-01, 9.54790963e-01, 6.11809713e-01, 6.91264866e-01, + 4.50402116e-01, 4.99215210e-01, 2.46185061e-01, 7.21885224e-01, + 8.59774301e-01, 6.32945619e-01, 5.54326262e-01, 3.29084388e-01, + 3.05617409e-01, 9.51080886e-01, 4.48145812e-01, 3.01954074e-01, + 2.38565150e-01, 1.16778491e-01, 6.11846618e-01, 3.11523695e-01, + 5.71679522e-01, 8.92536352e-02, 2.75055495e-01, 7.01036815e-01, + 9.59680220e-02, 8.95142111e-01, 1.49563921e-01, 7.21352887e-02, + 5.86497519e-01, 5.21234097e-01, 4.94624985e-01, 3.71474724e-01, + 5.91348911e-01, 6.07333893e-01, 6.90816381e-02, 8.18729415e-01, + 8.26887268e-01, 5.62247191e-01, 4.94071282e-01, 3.94966549e-01, + 4.10248006e-02, 9.91473084e-01, 6.48210683e-01, 2.29029461e-02, + 4.62800527e-01, 4.39322054e-01, 6.76484522e-02, 7.54381617e-01, + 3.77258368e-01, 8.22950883e-02, 4.63559653e-02, 5.14305768e-01, + 1.66000403e-01, 1.78812598e-01, 4.52404254e-01, 8.69937019e-01, + 9.41252026e-01, 8.66955146e-01, 8.43281460e-01, 5.80263735e-01, + 3.41063752e-01, 4.03031265e-01, 5.65100019e-01, 9.77042443e-01, + 9.60312975e-01, 5.74597787e-01, 3.22997391e-01, 3.24983262e-03, + 4.43717746e-01, 4.84440157e-02, 4.99642598e-01, 9.86758454e-01, + 2.39430788e-01, 2.72954938e-01, 6.89101173e-01, 1.05343160e-01, + 1.51451333e-01, 8.17604560e-01, 4.67208215e-01, 3.91459202e-01, + 2.95019639e-01, 2.12308619e-01, 9.77405041e-01, 4.45883911e-01, + 2.61725427e-01, 5.81538691e-01, 5.32163676e-01, 3.41124703e-01, + 4.22540898e-02, 3.34673505e-01, 5.30623929e-01, 1.71977789e-01, + 2.02391824e-01, 4.66763022e-01, 1.69646300e-01, 5.71158219e-01, + 2.81367419e-01, 3.00175865e-02, 2.64695268e-01, 1.74878228e-01, + 9.76519310e-01, 4.47659478e-01, 9.20272934e-01, 5.96409555e-01, + 8.05608036e-01, 3.57010393e-02, 3.46509876e-01, 7.09918963e-02, + 6.90741825e-01, 5.19830901e-01, 4.95382668e-01, 9.61290616e-01, + 5.84269319e-01, 4.17797161e-01, 4.99306400e-01, 5.27035244e-01, + 6.80189764e-01, 8.27000537e-01, 1.65090264e-01, 5.22092046e-01, + 9.20523407e-01, 1.26916933e-01, 3.85893941e-01, 6.35174634e-01, + 9.57707038e-01, 5.28992563e-01, 1.54301499e-02, 4.75420611e-01, + 7.15566162e-01, 5.27958597e-01, 5.55606993e-01, 9.60247033e-01, + 8.22291586e-01, 7.51029219e-01, 1.45883022e-01, 8.38413405e-01, + 8.65781042e-01, 8.24377868e-01, 7.81568539e-02, 1.26891712e-01, + 1.38031346e-03, 7.75500335e-01, 9.48710588e-01, 3.81408722e-01, + 1.64746349e-01, 8.88377109e-01, 8.11157608e-01, 3.39860001e-01, + 4.98714142e-01, 6.79524511e-01, 6.90549636e-01, 4.19235861e-01, + 1.31426596e-01, 9.90129353e-01, 1.84148211e-01, 8.84928443e-01, + 7.12377418e-01, 9.76875556e-01, 8.98814150e-02, 7.68618335e-01, + 8.45561565e-02, 3.09705936e-01, 6.54816947e-01, 4.53957285e-01, + 4.68819247e-01, 6.40443434e-01, 4.82574320e-01, 1.61372660e-01, + 3.95605753e-01, 8.69935741e-01, 2.62842218e-01, 2.47460397e-01, + 8.26392986e-01, 8.57707953e-01, 5.76341020e-01, 2.41623804e-01, + 5.91300628e-01, 9.52778904e-01, 5.14037592e-01, 9.17708707e-01, + 9.23785575e-03, 3.28763403e-01, 1.57797246e-01, 7.18657229e-01, + 3.60501782e-01, 9.30129805e-02, 4.75363634e-01, 3.04279184e-01, + 8.45091284e-01, 3.01276430e-01, 3.40465321e-01, 4.28886187e-01, + 9.78781396e-01, 8.54169086e-01, 6.38341944e-01, 4.64619203e-01, + 2.65765952e-01, 5.06275206e-01, 5.63721268e-01, 4.51954452e-01, + 4.92542437e-01, 9.11940222e-01, 8.38359977e-01, 9.29150234e-01, + 1.60692151e-01, 3.08964271e-02, 3.20939183e-01, 3.41793713e-01, + 5.80537490e-01, 3.23643526e-02, 8.97891963e-01, 3.81963795e-01, + 4.51738899e-01, 2.33627450e-01, 6.57701880e-02, 3.30771434e-03, + 5.35730019e-01, 2.23364027e-01, 1.57358442e-01, 6.35025306e-01, + 9.25867681e-01, 8.56266730e-01, 3.52743283e-01, 6.68675591e-01, + 8.09976694e-01, 6.13852521e-01, 6.97601550e-01, 8.80538459e-01, + 2.54339833e-01, 3.33018975e-01, 6.93243317e-01, 9.10659280e-01, + 1.42074388e-01, 7.51608793e-01, 6.99298513e-01, 2.58288129e-01, + 3.49495315e-01, 2.33849789e-01, 8.46564392e-01, 8.90943715e-01, + 9.33784580e-03, 6.52728571e-01, 9.57766470e-01, 9.99605088e-01, + 3.41270690e-01, 3.55749108e-01, 4.82152563e-01, 2.60748018e-01, + 3.42590207e-01, 6.20017115e-01, 9.34608756e-01, 3.06143816e-01, + 1.09871103e-01, 5.36889458e-01, 3.85075507e-01, 7.53351188e-02, + 4.14997198e-01, 6.75721252e-01, 1.73986032e-01, 7.71189221e-01, + 6.08687182e-01, 2.82456664e-01, 8.21634073e-01, 1.98445823e-01, + 7.06222028e-01, 7.18953881e-01, 1.45163974e-01, 2.27375731e-01, + 7.33401928e-01, 1.39474016e-01, 7.82123589e-01, 9.23668890e-01, + 7.36285897e-01, 6.07458628e-01, 5.53468166e-01, 1.85407203e-01, + 3.75851635e-01, 5.10271141e-01, 3.77489223e-01, 1.55826108e-01, + 8.89950821e-01, 3.95779383e-01, 4.57472320e-01, 3.72631196e-01, + 6.81495766e-01, 2.78016971e-01, 6.14441701e-01, 7.73257484e-01, + 2.10025067e-01, 6.06231429e-01, 2.99844256e-01, 4.53852635e-01, + 7.06533872e-01, 3.82879823e-01, 8.42117999e-01, 4.65437165e-01, + 1.76544219e-01, 5.23976674e-01, 4.52350121e-01, 1.92663687e-01, + 9.99791424e-01, 8.67203847e-01, 5.35944920e-01, 6.66215768e-01, + 3.11246435e-02, 7.14665289e-03, 7.17017593e-01, 7.61070647e-01, + 9.12223959e-02, 6.73599046e-01, 1.91914212e-01, 5.58608202e-01, + 3.06762453e-01, 1.55931034e-01, 4.81379786e-01, 1.05595014e-01, + 4.22827762e-01, 3.83889484e-01, 7.43034367e-01, 2.24671939e-01, + 3.68336104e-01, 9.16762664e-01, 3.67618388e-01, 8.09515385e-01, + 3.73714961e-02, 9.37971395e-02, 8.42187625e-01, 9.05109486e-01, + 6.60976043e-01, 3.10705842e-01, 9.93173393e-01, 3.01811127e-01, + 9.11479358e-01, 1.59420075e-02, 1.11314334e-02, 1.54423243e-01, + 7.07319219e-01, 1.04201914e-01, 1.67164800e-01, 3.84742863e-01, + 8.29670813e-01, 5.64450467e-01, 4.93541123e-01, 2.25852196e-01, + 2.79268903e-01, 4.68336333e-01, 7.67643027e-01, 3.26045618e-01, + 1.66074747e-01, 5.42368455e-01, 8.67129004e-01, 9.72701399e-01, + 4.61517776e-01, 2.07237922e-01, 9.62676273e-02, 3.29877702e-03, + 5.78787337e-01, 8.55082652e-01, 1.08945833e-01, 3.98497903e-01, + 3.48467374e-01, 7.66397761e-01, 2.30019198e-01, 4.46880840e-01, + 1.90051974e-01, 9.08894121e-01, 4.95022535e-01, 4.01705728e-01, + 3.20636743e-01, 5.45621811e-01, 3.71018447e-01, 7.69313410e-01, + 8.28828483e-01, 6.44787491e-01, 2.12075802e-01, 6.31437100e-01, + 1.24206253e-01, 4.73453290e-01, 3.63277586e-01, 5.01884188e-01, + 1.71657839e-01, 6.02734530e-01, 6.05350365e-02, 9.55851544e-01, + 3.04549527e-01, 8.41278743e-01, 7.41457774e-01, 3.06333738e-01, + 9.11953951e-01, 4.63394077e-01, 4.81171199e-01, 1.70314561e-01, + 4.35150316e-01, 4.86410721e-01, 8.07722744e-01, 3.68034827e-01, + 9.62094967e-01, 9.45490907e-01, 1.10607837e-01, 4.26591720e-01, + 6.22372888e-01, 8.83572543e-01, 8.46188854e-02, 1.69052711e-01, + 7.06886120e-01, 8.82981456e-01, 5.29281587e-01, 5.74586877e-02, + 4.29081546e-01, 4.14354395e-01, 3.65314255e-01, 7.83532800e-01, + 3.32110020e-01, 6.08405408e-01, 5.64444447e-01, 2.16211706e-01, + 3.21855456e-01, 2.41180251e-01, 4.55148147e-01, 2.12509192e-01, + 1.12307729e-01, 6.74607466e-01, 1.27040975e-01, 1.39491284e-01, + 8.22288489e-01, 5.68113234e-01, 5.74764335e-01, 4.76652415e-01, + 1.11665389e-01, 1.11783738e-01, 2.13890517e-01, 7.89757414e-01, + 7.81403625e-02, 2.68297404e-02, 2.65885716e-01, 7.46387206e-01, + 7.39411871e-01, 5.25267870e-01, 9.42619230e-01, 3.97874483e-01, + 7.18339912e-02, 8.23615397e-01, 4.08398782e-01, 3.43668757e-01, + 6.03074731e-01, 5.10383918e-01, 6.27840954e-01, 6.97145252e-02, + 9.00888877e-01, 1.26661522e-01, 2.95337277e-01, 5.79932981e-01, + 7.33427963e-01, 9.61112463e-01, 9.26330785e-01, 2.10094601e-01, + 2.58272584e-01, 1.55687519e-01, 1.09180007e-01, 7.28044570e-01, + 8.60183244e-01, 1.60864698e-01, 5.12122727e-01, 8.13197067e-01, + 3.27217443e-01, 7.05708258e-01, 5.72727972e-01, 5.48144922e-01, + 2.99803195e-01, 9.72500701e-01, 2.39011325e-01, 4.52917253e-01, + 7.80297653e-01, 4.38528229e-01, 5.42639679e-01, 5.47325062e-01, + 2.42309305e-01, 4.05688817e-01, 4.64691344e-01, 2.81563660e-01, + 9.43489399e-01, 4.40455281e-01, 9.25558601e-01, 8.30389488e-02, + 4.89887798e-01, 9.92106025e-01, 7.68970476e-01, 9.76514587e-01, + 2.61805215e-01, 4.11684641e-01, 5.40791370e-01, 8.40783825e-01, + 4.21549776e-01, 7.83450488e-01, 7.30292683e-01, 9.23913080e-01, + 4.67319969e-01, 3.13629695e-01, 3.28363476e-01, 8.11060578e-02, + 6.87123996e-01, 6.92536699e-01, 4.46294870e-01, 1.83603865e-01, + 4.71452870e-01, 6.86586110e-01, 1.42083389e-01, 4.17469287e-01, + 6.98730811e-01, 2.71533805e-02, 5.82939883e-02, 5.63764113e-01, + 7.24985811e-01, 1.83851662e-01, 7.38398679e-01, 2.77057629e-01, + 8.67415559e-01, 1.58987095e-01, 5.13459878e-01, 7.58446477e-01, + 7.45788160e-01, 5.66934387e-01, 9.38167265e-01, 2.82546046e-01, + 3.96147569e-01, 5.02663180e-01, 2.31342197e-01, 6.30795831e-01, + 1.89199376e-01, 2.96681036e-01, 6.26581606e-01, 1.91753154e-01, + 8.59379810e-01, 9.33910631e-01, 9.70077992e-01, 8.83391078e-01, + 5.74543989e-01, 7.04284185e-02, 2.40850647e-01, 1.65883512e-02, + 4.27448258e-01, 9.02076193e-01, 4.43181022e-01, 9.30162550e-01, + 3.57301521e-01, 6.55273491e-01, 9.18686998e-01, 8.33580458e-03, + 5.62394931e-01, 2.94211261e-01, 5.61407997e-01, 4.05998299e-01, + 1.37611464e-01, 8.33751326e-01, 6.73421474e-01, 2.23195257e-01, + 6.60437659e-01, 9.00612394e-01, 2.94803355e-01, 4.20194653e-01, + 2.44480138e-01, 5.35331529e-01, 3.82888594e-01, 2.22416883e-01, + 1.65714859e-02, 4.78892134e-02, 3.24885698e-01, 8.71487752e-01, + 2.08378965e-01, 8.12842007e-02, 7.14228356e-01, 2.62316935e-01, + 4.56956809e-01, 3.68001130e-01, 4.07526017e-01, 7.32032001e-01, + 7.43484586e-01, 3.48233201e-01, 3.81066270e-01, 4.86081359e-01, + 4.66253714e-01, 9.74099640e-01, 3.75932451e-01, 7.94005853e-01, + 8.20943824e-01, 5.23543229e-01, 1.44858882e-01, 6.63077315e-02, + 5.01059400e-01, 5.63884027e-01, 6.06887379e-01, 4.28211486e-01, + 6.73317074e-01, 1.64045058e-01, 3.91440262e-01, 8.80823336e-01, + 9.77298198e-01, 8.09425940e-01, 2.75909039e-01, 6.87867004e-01, + 4.31588607e-01, 4.67022700e-01, 5.89732658e-01, 7.31947510e-01, + 6.96354914e-01, 8.00263791e-02, 8.58996981e-01, 9.18389162e-01, + 2.96541314e-01, 3.17287244e-01, 2.24364202e-01, 7.58922521e-01, + 1.42886490e-01, 8.82789350e-01, 1.24438888e-02, 4.36305082e-01, + 8.40564499e-01, 5.14350046e-01, 3.53721806e-01, 7.54399467e-01, + 5.82851470e-01, 1.88329237e-01, 1.45590832e-01, 8.21202267e-01, + 4.07728003e-01, 5.79598930e-01, 5.88699662e-01, 8.13982852e-02, + 7.24101733e-01, 8.33166970e-02, 3.87799867e-01, 2.46674389e-01, + 8.50157642e-01, 5.10641951e-01, 2.47450744e-01, 7.31373513e-01, + 4.77583217e-01, 7.66172459e-01, 9.79793524e-01, 3.22170303e-01, + 7.69627578e-02, 5.96656107e-02, 3.75742821e-01, 4.13440636e-01, + 7.79305266e-01, 1.25088208e-01, 2.92053731e-02, 2.15121750e-01, + 9.27342881e-01, 9.27913992e-01, 5.58917456e-02, 2.73624253e-01, + 7.15506935e-01, 9.47043043e-01, 7.67851199e-01, 6.16052357e-01, + 5.04896165e-01, 1.91733830e-02, 9.11800664e-01, 3.26693749e-01, + 9.51929752e-01, 9.96364078e-01, 9.38893264e-01, 1.70436991e-01, + 2.15993682e-01, 8.81286026e-01, 2.40946280e-01, 6.00209011e-01, + 8.25817074e-01, 9.21595296e-01, 4.19138587e-01, 1.26089706e-01, + 5.45860338e-01, 2.49540348e-01, 9.38377778e-01, 4.90773058e-01, + 2.05905959e-01, 8.86396941e-02, 5.98758647e-01, 7.43958873e-01, + 5.11353848e-01, 9.06709409e-02, 4.20667261e-01, 1.62617320e-01, + 2.03806853e-01, 6.05816851e-01, 4.53797145e-01, 8.09602417e-02, + 6.54555481e-01, 9.19473336e-01, 7.90394742e-01, 1.10089574e-01, + 2.79094074e-02, 1.25150237e-01, 9.12672215e-01, 1.45895379e-01, + 4.05436418e-01, 3.63703747e-01, 2.52415683e-01, 7.78621136e-01, + 8.61324257e-01, 4.72151442e-01, 1.84795053e-01, 1.85572552e-01, + 9.30135884e-01, 2.97275684e-01, 8.06360319e-01, 7.10946726e-01, + 9.31014499e-01, 2.89522462e-01, 6.94432074e-01, 2.10209938e-01, + 4.19736192e-01, 9.37331626e-02, 1.43395136e-01, 2.71813950e-01, + 6.73682887e-01, 9.85545132e-01, 4.57019493e-01, 1.71615789e-01, + 6.50504376e-01, 7.19711026e-01, 7.61462110e-01, 2.74179207e-01, + 1.97967425e-02, 3.00849114e-01, 7.44025519e-01, 6.50661539e-01, + 8.45976633e-01, 5.73840375e-01, 2.12743148e-01, 1.21179424e-02, + 7.78704599e-01, 4.88697254e-01, 7.01110481e-01, 5.10569194e-02, + 3.32610269e-01, 5.48771905e-01, 7.69934632e-01, 5.53739089e-01, + 2.84435006e-01, 6.37823152e-01, 6.53037686e-01, 2.22101098e-01, + 8.01821047e-01, 2.41632157e-01, 3.67283323e-01, 6.71363389e-01, + 4.92522835e-01, 5.58951458e-01, 4.95279668e-01, 4.17524798e-01, + 2.82680269e-01, 7.05273743e-01, 4.97451830e-01, 1.85378453e-01, + 7.65216541e-01, 8.14400833e-01, 2.30582481e-01, 5.27812926e-01, + 6.71191707e-02, 7.13459175e-02, 4.25990016e-01, 2.69332594e-01, + 3.64065055e-01, 6.13207224e-01, 6.54219128e-03, 1.92975201e-01, + 4.04577739e-01, 8.07318510e-01, 6.86850738e-01, 1.88811204e-01, + 3.28074974e-01, 4.16432662e-01, 5.08629789e-02, 1.78805423e-01, + 4.38318656e-01, 2.63040373e-01, 4.38472169e-01, 1.03841694e-01, + 9.58585602e-01, 9.66770564e-01, 3.84663514e-01, 8.97998695e-01, + 8.90662562e-01, 7.49077534e-01, 4.84078317e-01, 7.82234229e-01, + 9.30449711e-01, 3.38727778e-01, 1.73964968e-01, 6.82044981e-01, + 7.02122165e-01, 3.79070306e-01, 2.49612241e-01, 2.08405008e-02, + 8.05092459e-01, 1.57284560e-01, 5.91389808e-02, 3.83195325e-01, + 8.89476629e-01, 2.56531357e-01, 8.15103159e-01, 5.06856367e-01, + 2.47126190e-01, 1.52176371e-01, 3.79095646e-01, 3.19186802e-02, + 5.01105511e-01, 4.50405879e-01, 3.21774373e-01, 8.09024282e-01, + 3.46115199e-01, 5.26717641e-01, 6.37729593e-01, 5.31478634e-01, + 2.32021169e-01, 3.90873089e-01, 5.32944586e-03, 3.64276517e-03, + 2.27834546e-01, 3.69192673e-01, 3.35594527e-02, 8.00989203e-01, + 8.05845643e-01, 2.16534405e-01, 5.39999970e-01, 7.84868427e-01, + 5.25406153e-01, 9.27249061e-01, 8.92506145e-01, 2.20461272e-01, + 7.80199844e-01, 8.64680944e-01, 9.78627472e-01, 3.81483734e-01, + 3.12434676e-01, 2.04898313e-01, 1.73629115e-01, 2.15692299e-01, + 7.80958721e-01, 1.51202230e-01, 1.69168895e-01, 2.15583217e-01, + 3.44120865e-01, 4.88521616e-02, 3.31308723e-01, 1.37062472e-01, + 6.50381691e-01, 1.88296372e-01, 9.34046820e-01, 7.30696527e-01, + 9.30405829e-03, 5.99018954e-01, 3.12655109e-01, 4.61871480e-01, + 7.65057148e-01, 7.79658279e-01, 2.25162670e-01, 9.37780078e-01, + 1.64880929e-01, 4.91960732e-01, 8.09264576e-01, 6.42863915e-01, + 3.25077074e-01, 9.73669255e-01, 4.09034971e-01, 6.07480779e-01, + 1.83313776e-01, 3.86817713e-01, 8.14587592e-01, 3.13004183e-01, + 9.89656700e-01, 9.55616603e-01, 6.42334501e-01, 2.57652921e-01, + 5.95720064e-02, 1.30968950e-01, 2.42594329e-01, 7.52288037e-01, + 3.63044859e-01, 6.45670237e-01, 6.22836299e-01, 8.79067557e-01, + 6.48974979e-04, 6.91664945e-01, 6.87863458e-01, 3.71855520e-01, + 4.02740498e-01, 3.88189326e-01, 6.72183816e-01, 3.73681540e-01, + 7.43587826e-01, 5.23862689e-02, 7.00812999e-01, 8.92570144e-01, + 8.86718049e-01, 1.53632573e-01, 3.69305544e-01, 7.43666709e-01, + 9.52462318e-01, 2.85450411e-02, 3.09484190e-01, 6.09192606e-01, + 4.81734621e-01, 2.31387310e-01, 4.13994788e-01, 3.00968231e-01, + 3.40759084e-01, 4.98786943e-01, 6.85560874e-01, 7.82722760e-01, + 6.27622972e-01, 5.96122860e-01, 3.17137379e-01, 9.30014080e-01, + 3.31774171e-01, 6.98475397e-01, 4.30631692e-01, 7.57323636e-01, + 8.72939052e-01, 5.98425737e-01, 1.52484889e-01, 6.77486994e-01, + 1.56680174e-01, 8.38184526e-01, 7.05223637e-02, 6.32973781e-01, + 5.67406256e-01, 1.05895757e-01, 2.05018894e-01, 6.45525360e-01, + 8.53119159e-01, 2.58419660e-01, 7.36201227e-01, 1.36931145e-01, + 5.57804729e-01, 8.88445302e-01, 6.18788759e-01, 4.40342525e-02, + 4.48816112e-01, 3.55887574e-01, 2.79451134e-01, 1.94955589e-01, + 1.49149324e-01, 9.26957117e-01, 5.94401777e-01, 4.34953168e-01, + 1.72150495e-01, 6.92512560e-01, 6.25659912e-01, 3.53498143e-01, + 4.71827291e-01, 5.48081618e-01, 6.63612391e-01, 7.77597371e-01, + 6.16132267e-01, 2.08793095e-01, 6.54370435e-01, 1.43840575e-02, + 9.26190660e-01, 4.56657569e-01, 1.34607758e-01, 8.46929024e-01, + 1.35479425e-01, 2.73481937e-01, 7.17504372e-01, 6.37246114e-01, + 8.73057171e-02, 1.18451214e-01, 4.87062980e-01, 4.68357032e-01, + 8.14067903e-01, 4.51290963e-02, 8.29995544e-01, 6.92731492e-01, + 4.48054234e-01, 8.08294511e-01, 4.38437815e-01, 9.73087600e-01, + 4.00556362e-01, 2.69210482e-01, 1.90812992e-01, 5.51737526e-01, + 8.09240931e-01, 7.02383255e-01, 9.15284278e-01, 4.71743432e-01, + 4.59917451e-01, 8.27426537e-02, 2.45649835e-02, 3.69984986e-01, + 2.26854883e-01, 1.08020133e-02, 3.29332615e-01, 7.77787273e-01, + 1.93492145e-01, 1.26887826e-01, 2.05285278e-01, 8.06330950e-01, + 3.36846101e-01, 4.28305953e-01, 4.46631616e-01, 1.83568397e-01, + 2.66010074e-01, 1.65533118e-01, 1.97149723e-01, 5.32596310e-01, + 1.31690898e-01, 1.97358686e-01, 3.60311616e-01, 2.34873690e-03, + 4.48739574e-01, 9.42011656e-02, 5.54537272e-01, 5.71754325e-01, + 4.42570791e-01, 7.23765411e-01, 1.68230254e-01, 1.08387844e-01, + 5.63240383e-01, 4.01449664e-02, 7.61878137e-01, 1.84468654e-01, + 7.27330001e-01, 5.70071191e-01, 4.30589309e-01, 8.06933802e-01, + 7.63083913e-01, 4.57054100e-02, 4.22801640e-02, 2.98273838e-01, + 9.94959222e-02, 5.37861705e-01, 9.47728339e-01, 2.35664881e-01, + 9.13932722e-01, 5.27830511e-01, 6.74554633e-01, 8.57226688e-01, + 5.69486299e-01, 5.96239075e-01, 3.44143844e-01, 7.71420730e-01, + 4.03462919e-01, 9.37676468e-01, 6.77939033e-01, 2.94911434e-01, + 8.60944883e-01, 3.97559830e-01, 8.86311983e-01, 9.38773684e-01, + 7.48799949e-01, 2.97265126e-02, 1.91238378e-01, 6.70884380e-02, + 5.78494516e-01, 8.66223057e-01, 5.15415199e-01, 5.97494999e-01, + 1.59946407e-01, 7.89974807e-01, 2.14214317e-01, 7.44879854e-01, + 9.91802395e-01, 8.80220536e-01, 3.98768117e-01, 3.17062606e-01, + 7.43774361e-01, 1.06819069e-01, 1.19235994e-01, 4.66647578e-01, + 4.82252315e-01, 6.63605732e-01, 9.32703913e-01, 1.38701279e-01, + 7.68670880e-01, 7.74230520e-01, 1.86931163e-01, 1.70265692e-01, + 2.75324570e-01, 6.57024567e-01, 9.27178040e-01, 3.24600460e-01, + 2.04220815e-01, 2.07875855e-01, 2.46589386e-02, 1.38795806e-01, + 5.90669097e-01, 8.46731862e-01, 5.01410464e-01, 1.45896367e-01, + 8.23831270e-01, 4.14099435e-01, 9.71332618e-02, 2.90665493e-01, + 5.16384862e-01, 7.81727718e-01, 4.07094101e-01, 4.70877992e-01, + 1.01125711e-02, 3.16454365e-01, 3.82201931e-01, 1.52362350e-01, + 7.28666989e-01, 5.09648353e-01, 2.24362272e-01, 7.93638860e-01, + 8.08595046e-01, 6.35321300e-01, 4.17604409e-01, 8.82336315e-01, + 6.55471605e-01, 9.06895005e-02, 5.25419591e-01, 5.03960948e-01, + 3.50978545e-01, 5.67369898e-01, 2.43048693e-01, 9.29878699e-01, + 2.52345597e-01, 8.11768754e-01, 8.37755411e-02, 5.81591995e-01, + 9.83338281e-01, 4.08169290e-01, 1.67416200e-02, 4.52875430e-01, + 2.35908133e-01, 9.29729555e-01, 3.01862977e-01, 2.32592566e-01, + 5.50182274e-01, 5.94175838e-01, 9.11763820e-01, 4.88732970e-01, + 5.82374445e-02, 5.07425182e-01, 3.97872802e-01, 8.75702431e-01, + 9.26584641e-02, 1.34032927e-01, 8.65220290e-01, 4.77646068e-01, + 5.64651160e-01, 5.63868203e-01, 7.01066889e-01, 9.99257628e-01, + 7.93438387e-01, 7.78084453e-01, 3.83886275e-01, 1.32247747e-01, + 4.56877338e-01, 9.40869768e-01, 1.36509984e-01, 2.29776542e-01, + 5.43033288e-01, 2.51027044e-01, 4.63625930e-01, 6.51180968e-01, + 2.84967568e-01, 1.34521984e-01, 6.69720541e-01, 5.79746270e-02, + 6.81434555e-01, 8.19918480e-01, 1.91151688e-01, 4.21222853e-01, + 7.44794385e-01, 5.62816145e-01, 4.80949879e-01, 6.63528890e-01, + 9.78588328e-01, 2.46133367e-01, 5.91653223e-01, 4.53955601e-01, + 4.34925991e-01, 7.95123585e-01, 2.32427310e-01, 2.27812208e-01, + 1.07205790e-01, 1.02686916e-01, 7.28310993e-02, 2.78261852e-01, + 2.68999714e-01, 1.66088784e-01, 3.03924331e-01, 4.55757123e-01, + 6.97771791e-01, 4.21998035e-01, 7.54431832e-01, 9.88895379e-01, + 5.97588223e-01, 7.77827250e-01, 7.77500552e-01, 7.03786443e-01, + 8.22440262e-01, 5.29597210e-01, 4.36723859e-01, 2.61172795e-01, + 4.35589756e-02, 8.84028111e-01, 5.20544547e-01, 4.22808978e-01, + 5.45181312e-01, 3.22776591e-01, 3.86414085e-01, 9.99154375e-02, + 5.46774851e-01, 6.10197494e-01, 3.16390676e-02, 1.42365823e-01, + 9.28158768e-01, 5.34010927e-01, 1.72812266e-01, 9.62072403e-01, + 6.07521297e-01, 8.16682161e-01, 2.81779552e-01, 4.89829310e-01, + 9.76036227e-02, 2.49798366e-01, 8.50868597e-01, 5.97667258e-01, + 3.39458934e-01, 3.61594764e-01, 3.80919254e-01, 6.61079185e-01, + 9.97603734e-01, 9.09711271e-01, 6.27221370e-01, 6.22777737e-01, + 7.68377872e-01, 6.56516663e-01, 2.25970216e-01, 9.65843632e-01, + 5.77998070e-01, 1.50513870e-01, 7.88508245e-01, 8.82018262e-01, + 2.76371417e-01, 4.73529010e-01, 5.71800915e-02, 4.89584218e-01, + 1.58490570e-01, 3.42111655e-01, 3.48976136e-01, 1.44284027e-01, + 2.22259783e-01, 2.20498807e-01, 7.23087804e-01, 5.17512078e-01, + 5.65352234e-01, 2.97036670e-02, 1.47812718e-01, 6.02454544e-02, + 3.32616659e-01, 1.87872302e-01, 4.76274692e-01, 1.99111440e-02, + 8.07035806e-01, 7.84594619e-01, 9.45455012e-01, 5.39322469e-01, + 4.70902384e-01, 7.79997446e-01, 7.86715314e-01, 7.91430847e-01, + 3.84430392e-01, 6.49550123e-01, 8.03483297e-01, 2.35005171e-01, + 2.93060411e-01, 5.31369131e-01, 7.98171439e-01, 4.49250456e-01, + 1.54089399e-01, 8.06936625e-01, 6.39637642e-02, 1.36853554e-01, + 5.09745299e-01, 8.93579563e-01, 6.32363365e-01, 8.65776056e-02, + 8.46022663e-01, 9.78977986e-01, 1.47910911e-01, 2.79207510e-01, + 7.08750221e-01, 3.08393344e-01, 3.35176457e-02, 7.81951392e-01, + 6.79692719e-02, 1.05858743e-01, 6.66655250e-01, 9.96118373e-01, + 2.33087251e-01, 8.49960603e-01, 6.61580142e-02, 2.35052199e-01, + 5.37827220e-01, 5.40735552e-01, 9.53034646e-01, 5.48703907e-01, + 2.42244973e-01, 6.53147914e-01, 4.93824069e-02, 3.00251928e-01, + 7.89499915e-01, 9.67129119e-01, 5.41588563e-01, 2.05451025e-01, + 2.16913899e-01, 2.63927483e-01, 8.40947650e-01, 7.94181582e-02, + 5.76829660e-01, 5.35626666e-01, 1.95532371e-01, 8.71653894e-01, + 3.80292233e-01, 6.40770559e-01, 7.07799130e-01, 1.95603700e-01, + 4.37961828e-01, 1.95078268e-01, 8.46076613e-01, 4.21713362e-01, + 6.80019446e-01, 1.45723452e-02, 5.78566880e-01, 4.63484866e-01, + 6.62339714e-01, 6.02328370e-01, 4.48952916e-02, 9.56569583e-01, + 9.23635181e-01, 3.96692622e-01, 9.19312566e-02, 9.88443936e-01, + 3.88401164e-01, 5.11607845e-01, 5.52134003e-02, 6.33146212e-01, + 5.14667745e-01, 5.00996886e-01, 9.21919280e-01, 6.57929777e-01, + 7.30453664e-01, 2.67124774e-01, 8.39803649e-01, 5.94649771e-01, + 5.20037425e-01, 6.13862103e-01, 4.24800132e-01, 8.31986162e-01, + 5.45384318e-02, 5.69380895e-01, 5.25750994e-01, 3.64508777e-01, + 5.90030365e-01, 9.52076470e-01, 1.12719576e-01, 3.29530138e-01, + 1.06193364e-01, 5.69039285e-01, 4.82057358e-01, 8.19919084e-02, + 8.56077223e-01, 8.37346876e-02, 8.06609845e-01, 6.16729834e-01, + 5.24836850e-01, 7.70617407e-01, 7.64831307e-01, 8.96567554e-01, + 5.24420117e-01, 2.77623259e-01, 3.22800389e-01, 8.56595438e-01, + 7.97408897e-01, 9.84336322e-01, 6.05872705e-01, 1.72064448e-01, + 3.39865874e-01, 1.07895600e-01, 6.35505667e-01, 7.17785020e-01, + 4.54956674e-02, 8.40944711e-01, 9.09263046e-01, 7.23253622e-01, + 6.08397636e-01, 4.28223693e-01, 3.49143495e-01, 5.17343768e-01, + 3.03931241e-02, 2.58809922e-01, 6.26347058e-01, 2.58317379e-01, + 7.70094729e-02, 4.90677171e-01, 6.23578413e-01, 7.39323402e-01, + 7.86430216e-01, 1.95871033e-01, 9.59352018e-01, 9.48050021e-01, + 4.04923161e-01, 5.48466997e-01, 6.32778119e-01, 9.27004568e-01, + 4.60867852e-01, 6.18367404e-02, 4.49117997e-01, 5.72517365e-02, + 7.42512152e-01, 8.52078457e-01, 9.18500080e-01, 7.53443248e-01, + 8.79991036e-01, 7.73933267e-01, 8.12208158e-01, 5.08698053e-01, + 4.83453257e-01, 1.40564155e-01, 4.63751858e-01, 6.94391333e-02, + 5.67141354e-01, 4.81644035e-01, 7.99300967e-01, 3.42458925e-01, + 7.13255922e-01, 7.30373655e-01, 2.54026166e-01, 8.92656780e-01, + 3.43299490e-01, 2.91557217e-01, 7.04476359e-01, 6.38560693e-01, + 5.97876994e-01, 9.14060350e-01, 7.10507406e-01, 5.27871014e-01, + 1.37971080e-03, 8.49668317e-01, 4.03172758e-01, 1.69417224e-01, + 9.15704212e-02, 5.80469353e-02, 2.86447181e-02, 4.22680837e-01, + 2.75320503e-01, 7.19456317e-01, 5.54424190e-01, 4.19628151e-01, + 9.03261398e-01, 2.40076435e-01, 6.24940979e-02, 7.68350219e-01, + 8.16259858e-01, 4.07364240e-01, 1.90892373e-01, 2.24645957e-01, + 2.68513102e-01, 8.59940842e-01, 4.26799814e-01, 9.34924639e-02, + 5.04900452e-01, 6.19869474e-01, 1.39149678e-01, 3.32084425e-02, + 2.04821361e-01, 1.52667263e-01, 7.59186101e-01, 1.77790763e-01, + 5.40029943e-01, 5.39653163e-02, 1.08297347e-01, 1.95635060e-01, + 1.14453063e-01, 3.34717092e-02, 9.73972485e-01, 9.49581829e-01, + 7.09210000e-01, 1.83736580e-01, 7.98625861e-01, 2.06249983e-01, + 8.11163305e-01, 7.09788798e-01, 7.31928595e-01, 7.06239329e-01, + 4.61273623e-01, 1.47860630e-01, 7.97788920e-01, 2.53221786e-02, + 1.08083311e-01, 1.76009409e-01, 4.57938076e-01, 8.47280675e-01, + 9.33968107e-01, 2.36854123e-01, 4.25184701e-01, 6.06357301e-02, + 7.30137098e-01, 1.82268678e-01, 9.19488237e-01, 4.59848807e-02, + 9.82461133e-01, 7.36827770e-01, 3.94792587e-02, 1.05485901e-01, + 9.04068922e-01, 5.89364625e-01, 5.82999420e-01, 9.84180524e-01, + 8.39599561e-01, 8.16253555e-01, 1.88702947e-01, 9.34650148e-01, + 5.54412280e-01, 6.74554821e-01, 7.44570651e-01, 4.93609876e-01, + 3.85316007e-01, 5.88890462e-01, 9.59817567e-01, 6.49085393e-01, + 5.08310855e-01, 6.46559754e-01, 6.26565112e-01, 3.42146898e-01, + 3.88847276e-01, 2.82999302e-01, 3.32617413e-01, 3.60441738e-01, + 6.15696983e-02, 8.09875704e-02, 3.93702137e-01, 9.00132344e-01, + 2.87506971e-01, 5.79431727e-01, 8.15253471e-01, 9.52292387e-01, + 6.68236002e-01, 9.92367542e-01, 9.96548846e-01, 8.44550511e-01, + 8.24719137e-01, 7.65994828e-01, 1.09263635e-01, 6.38947299e-01, + 5.79485650e-01, 1.85070162e-01, 7.27596719e-01, 5.95479534e-01, + 4.17556122e-01, 4.80422572e-01, 6.77294362e-01, 8.18737713e-01, + 8.03728185e-01, 6.29570464e-01, 8.86369135e-01, 9.83240973e-02, + 7.91938800e-01, 4.55609898e-01, 7.42090017e-01, 6.49227163e-01, + 1.38344917e-01, 5.73024319e-01, 1.42592663e-01, 1.47296755e-01, + 9.05088934e-01, 3.32192389e-01, 8.80267050e-01, 3.43224412e-02, + 6.15051147e-01, 3.09894837e-01, 4.48333590e-01, 3.08905528e-01, + 7.19655202e-01, 5.08634603e-01, 7.24210742e-01, 8.49162045e-01, + 7.39923339e-01, 4.28078649e-01, 7.73026762e-01, 5.58670880e-01, + 2.14258147e-01, 2.56797489e-01, 3.64649241e-01, 1.90313112e-01, + 1.59470431e-01, 4.12877241e-02, 1.15591053e-01, 2.61831664e-02, + 4.47307902e-01, 3.46625095e-01, 7.02788265e-01, 1.42473756e-02, + 9.14824501e-01, 8.90997679e-01, 7.89556999e-01, 3.15688565e-01, + 5.47100304e-02, 1.72920709e-01, 6.34539788e-01, 2.66849962e-01, + 3.90958160e-01, 9.91716809e-01, 2.50697140e-01, 2.00590811e-01, + 7.04236260e-01, 8.60993346e-01, 9.60179095e-01, 4.93160964e-01, + 5.64962057e-01, 8.91017606e-01, 3.90111599e-01, 9.18168639e-01, + 5.18288168e-01, 9.37449134e-01, 8.92922549e-01, 8.52365292e-01, + 5.33240791e-01, 6.93511885e-02, 6.13448765e-01, 1.69536026e-01, + 5.34564717e-03, 3.54464573e-01, 1.31301275e-01, 2.49233573e-01, + 7.83740348e-01, 8.27472899e-01, 1.02076185e-01, 2.13321521e-01, + 8.39823926e-01, 2.96124623e-01, 5.32126642e-01, 9.37173836e-03, + 3.32925900e-01, 8.61626197e-01, 1.59908436e-01, 9.54738379e-01, + 3.71265604e-01, 4.63355901e-01, 8.17367258e-01, 5.54249630e-01, + 3.91232958e-01, 2.83533793e-01, 3.76686578e-02, 8.18705432e-01, + 1.14308247e-01, 1.35529656e-01, 3.56726257e-01, 3.82159013e-01, + 1.90242846e-01, 6.27398094e-01, 7.42727283e-01, 2.53052257e-01, + 2.92263497e-01, 8.36861838e-01, 8.80117657e-01, 4.24251998e-01, + 2.42857082e-01, 3.26912947e-01, 2.38978271e-02, 3.87288511e-01, + 8.38786160e-01, 2.76140434e-02, 1.41603539e-01, 2.45213250e-01, + 9.01979435e-01, 7.98300877e-01, 6.28114620e-02, 3.39538356e-01, + 9.98955922e-01, 8.83984654e-01, 3.25924686e-02, 2.66477681e-01, + 9.87529006e-01, 3.94806394e-01, 1.79714717e-02, 7.22094984e-01, + 8.43448057e-01, 2.97094385e-01, 6.30082031e-01, 4.69114638e-01, + 7.56449205e-01, 5.39852806e-01, 6.64231525e-01, 2.56561259e-01, + 1.69032579e-01, 6.35520653e-01, 5.32374143e-01, 2.41790269e-01, + 1.31880241e-01, 7.21668905e-01, 8.49549657e-01, 9.51179163e-01, + 9.31236210e-01, 1.60580056e-01, 4.81987713e-02, 8.55740104e-01, + 2.33510121e-01, 8.06852287e-01, 8.36335316e-01, 4.08700026e-02, + 3.01354537e-01, 7.04597923e-01, 5.72346977e-01, 6.20919695e-01, + 5.61694124e-01, 7.33794430e-01, 6.94145175e-01, 4.53505475e-01, + 7.55109956e-01, 8.14496494e-01, 6.46203394e-01, 4.60737495e-01, + 6.54667111e-01, 5.35883231e-01, 9.59617583e-01, 7.20299072e-01, + 9.15563119e-02, 7.21026109e-01, 4.67450149e-01, 7.34462257e-01, + 7.99462181e-01, 2.68883715e-01, 9.28422756e-01, 3.00536442e-01, + 7.14940787e-01, 6.83090883e-01, 1.76575309e-01, 5.80842227e-02, + 8.21636031e-01, 7.98096674e-02, 4.11193499e-01, 5.52466051e-01, + 7.67632729e-01, 4.98006389e-01, 4.32751169e-01, 2.97660033e-01, + 6.00292000e-01, 3.13053918e-01, 7.06950914e-01, 7.73032205e-01, + 3.39058015e-01, 7.45874867e-01, 2.94171799e-01, 2.87739192e-01, + 3.66448107e-01, 7.90110213e-01, 9.46773396e-01, 6.61030817e-01, + 8.28805709e-01, 3.68350359e-01, 9.01018421e-01, 5.58504106e-01, + 3.87886907e-01, 4.53400553e-01, 5.36041878e-01, 9.40252927e-01, + 6.32877657e-01, 8.17582446e-01, 6.60348688e-01, 7.84982408e-01, + 4.70946735e-01, 4.22792289e-01, 1.15773673e-01, 7.85006539e-01, + 6.60265886e-01, 8.06774887e-01, 4.58476060e-01, 5.72138920e-01, + 9.41565763e-02, 3.07655221e-01, 7.62754808e-01, 7.59367227e-02, + 5.02760941e-01, 3.31379403e-02, 6.97535587e-01, 6.63730619e-01, + 8.13759447e-01, 5.80630029e-02, 9.90930123e-01, 8.62673324e-01, + 7.59293522e-01, 8.87188097e-01, 6.15587858e-01, 4.74667163e-01, + 5.12807468e-01, 9.86933916e-01, 7.91295121e-01, 3.03786248e-01, + 9.72577890e-01, 5.18621477e-01, 1.42679940e-01, 6.23338740e-01, + 6.40711239e-01, 9.89085235e-01, 6.54985281e-01, 7.57553525e-01, + 6.65357528e-01, 4.80734243e-01, 9.40583203e-01, 4.85679346e-01, + 5.79304551e-01, 3.25099620e-01, 2.59389691e-01, 5.71960521e-01, + 2.63128068e-01, 4.61009923e-01, 4.47025639e-02, 3.52733473e-02, + 2.77707989e-01, 2.37116023e-01, 8.84448709e-01, 3.04657122e-02, + 2.38680052e-01, 7.03965210e-01, 8.58533546e-01, 5.75351731e-01, + 9.72826173e-01, 7.90426471e-01, 8.22624728e-01, 8.53964640e-01, + 7.70330678e-01, 1.92417498e-01, 2.86306961e-01, 3.65725047e-01, + 6.34083990e-01, 4.22059202e-01, 8.37637313e-01, 7.01322018e-01, + 9.16658031e-01, 9.59801062e-01, 8.27736271e-01, 3.75673003e-01, + 4.94315067e-01, 4.48762864e-01, 5.99333709e-01, 7.00869026e-01, + 5.90852451e-01, 9.99524217e-01, 6.62704721e-02, 2.20955862e-01, + 6.88692705e-01, 2.94846178e-01, 8.03357822e-01, 9.87092429e-01, + 1.39423869e-01, 4.11924707e-01, 5.67289118e-01, 6.38548666e-02, + 5.46612866e-01, 9.99390104e-01, 9.24665265e-02, 5.65808119e-01, + 4.33145041e-02, 2.85775584e-01, 3.05153883e-01, 3.35801307e-01, + 4.47778090e-01, 7.92308286e-01, 5.14027224e-01, 5.41968344e-01, + 8.49974156e-01, 4.95159145e-01, 3.41339561e-03, 2.02271820e-01, + 9.56276383e-02, 4.90971131e-01, 5.21295786e-01, 5.42892847e-01, + 6.26040319e-01, 8.85220690e-02, 2.99885797e-01, 7.68347901e-01, + 3.78608811e-02, 8.21087965e-01, 3.78189165e-01, 4.69839343e-01, + 8.48830049e-01, 2.20051672e-01, 1.84346607e-01, 3.35279438e-01, + 2.22260001e-01, 2.11140889e-01, 2.65866059e-01, 3.79417370e-01, + 7.32603485e-02, 2.02974235e-02, 3.17654644e-01, 3.19123230e-01, + 5.10658015e-01, 7.94214613e-01, 5.87610392e-01, 5.71706229e-01, + 5.82713135e-01, 9.65731692e-01, 7.47778571e-01, 1.06282990e-01, + 4.61777308e-01, 5.07590624e-01, 1.55575790e-01, 8.56965796e-01, + 5.41864428e-01, 2.81549341e-01, 6.72815889e-01, 1.98717142e-01, + 4.34212604e-01, 6.64007833e-01, 8.06428943e-01, 9.72578580e-01, + 8.73359588e-01, 3.59833169e-01, 1.52169598e-01, 2.36812799e-01, + 3.17308214e-01, 4.26665454e-02, 1.22512713e-01, 4.05887410e-01, + 3.94635327e-01, 3.68368934e-02, 3.49016215e-01, 8.38410709e-01, + 9.23341580e-01, 8.78149070e-01, 6.72170048e-01, 4.79080022e-01, + 1.76197102e-01, 9.70706114e-01, 7.46602218e-01, 7.83664886e-01, + 4.36771835e-01, 6.58181637e-01, 3.38112165e-01, 8.31991302e-01, + 6.69758962e-01, 7.19515257e-01, 9.63824555e-01, 7.04025455e-01, + 8.07361051e-03, 8.22656090e-01, 6.68232709e-01, 9.86633387e-01, + 9.31587947e-01, 1.89205641e-01, 8.31760559e-01, 3.99644613e-01, + 5.49750466e-01, 3.26770512e-01, 6.23341186e-01, 3.34890896e-02, + 1.25361895e-02, 6.75823497e-01, 8.52968623e-01, 2.28659041e-01, + 9.92708833e-01, 8.85488472e-01, 9.92329920e-01, 5.57386714e-01, + 2.35817451e-01, 7.40349073e-01, 5.38877219e-01, 5.74460419e-01, + 7.72192466e-01, 7.64336567e-01, 6.74542062e-01, 1.62896787e-01, + 2.61742322e-01, 5.72680831e-01, 6.99712111e-01, 9.74436138e-01, + 2.80347461e-01, 6.08853032e-01, 6.91366377e-01, 7.31669555e-01, + 3.50676919e-01, 6.92695805e-01, 2.48933946e-01, 6.05741327e-01, + 9.32503295e-01, 5.24577289e-01, 8.91639308e-01, 2.74987654e-01, + 3.64413512e-01, 1.56359440e-01, 5.09185290e-01, 4.48479242e-01, + 7.90023320e-01, 1.24554957e-01, 6.21422182e-01, 5.52338075e-02, + 3.68692332e-02, 2.00019543e-01, 9.27458438e-01, 3.92990899e-01, + 4.21673525e-02, 7.70416563e-01, 8.86621220e-01, 7.55030905e-01, + 2.13003787e-01, 5.20746996e-01, 1.77610089e-01, 2.76658040e-01, + 5.34957940e-01, 5.07861890e-01, 9.39110894e-01, 5.49537100e-01, + 8.68028448e-01, 2.16525558e-01, 1.97140706e-01, 3.49594827e-01, + 3.54786930e-02, 1.25642055e-01, 3.23148854e-01, 6.59144483e-01, + 6.73652474e-02, 8.20217976e-01, 1.86125028e-01, 2.72470316e-01, + 4.53537023e-01, 7.38119238e-01, 4.63841811e-01, 6.22931735e-01, + 4.95265620e-01, 6.14475291e-01, 3.51725884e-01, 5.56822091e-02, + 4.21759674e-01, 5.24325777e-01, 2.66436258e-01, 5.01266626e-01, + 8.27531598e-03, 4.17005354e-01, 9.39479931e-01, 8.76098365e-01, + 8.88392722e-01, 2.85271817e-01, 8.34833471e-01, 5.64586137e-01, + 7.77844836e-02, 2.61251905e-01, 6.48985720e-01, 6.03212973e-01, + 8.78170613e-01, 2.77922683e-01, 6.65340300e-01, 2.95590225e-01, + 1.94139083e-01, 9.97260166e-01, 4.27979004e-01, 1.46587201e-01, + 9.14098680e-01, 5.54870417e-01, 3.04025847e-02, 9.57974410e-01, + 8.87549419e-01, 7.09466012e-01, 2.71466554e-01, 9.92152475e-02, + 9.75994038e-01, 2.38892332e-01, 9.13048467e-01, 9.46067934e-01, + 4.29107264e-01, 4.94560570e-01, 2.46311003e-01, 8.04130839e-01, + 3.49338353e-01, 8.20269578e-01, 2.41718153e-01, 8.05506434e-01, + 9.83580808e-01, 5.09911997e-02, 7.40563267e-02, 2.74853859e-02, + 3.48562564e-02, 8.43584418e-01, 3.32971919e-01, 2.23330229e-01, + 6.81656029e-01, 8.93232502e-02, 9.14066333e-02, 3.51538343e-01, + 7.69332041e-01, 4.20118553e-01, 6.06463056e-01, 4.85176247e-01, + 3.34052122e-01, 8.35118023e-01, 5.06263115e-02, 7.02983225e-01, + 5.46352422e-01, 9.84490191e-01, 7.13189407e-01, 2.44420584e-01, + 2.38207534e-01, 5.19293675e-01, 1.70908671e-01, 4.27618052e-01, + 5.29870241e-02, 8.17518931e-01, 4.27241004e-01, 2.56208965e-01, + 3.77940215e-01, 7.98871644e-02, 3.72998241e-01, 2.33430622e-01, + 7.66957776e-01, 3.37328625e-01, 8.43431734e-01, 3.14068010e-01, + 7.11371765e-01, 6.02345944e-01, 3.68904626e-01, 8.64697423e-01, + 4.07108753e-01, 2.16111030e-02, 2.14349295e-01, 7.70115577e-01, + 2.86861456e-01, 9.58923829e-01, 5.04839384e-01, 4.26919575e-01, + 3.44502146e-01, 5.30290335e-01, 8.84382228e-01, 5.75249467e-01, + 2.15944689e-01, 1.68629113e-01, 7.18216688e-01, 8.98706455e-01, + 7.56085076e-01, 1.69716123e-01, 6.92024773e-01, 2.71360510e-01, + 4.09984490e-01, 2.65937395e-01, 7.22243688e-01, 5.47279785e-01, + 6.32263300e-01, 6.94593903e-02, 9.10246244e-01, 9.29194032e-01, + 1.04722871e-01, 7.40824097e-01, 9.55011084e-01, 3.38004297e-01, + 6.15096449e-01, 4.47571950e-01, 6.10133913e-01, 7.33553351e-03, + 2.00805149e-01, 4.48893133e-01, 7.85674044e-01, 9.21148806e-01, + 9.50452261e-01, 6.53467376e-01, 1.99568002e-01, 2.62917738e-01, + 3.36655772e-01, 3.26309328e-01, 9.64056551e-01, 6.34673709e-01, + 8.84606346e-01, 1.72232592e-01, 5.06183907e-01, 7.48059744e-01, + 1.11917738e-01, 2.13407378e-01, 8.46829291e-01, 7.08922828e-02, + 4.75820652e-04, 9.80558932e-01, 9.03841391e-01, 3.61414975e-01, + 3.94521239e-01, 3.06723640e-01, 1.86482445e-01, 3.23159685e-01, + 3.04486261e-01, 2.17553013e-01, 2.30987652e-01, 1.34657490e-01, + 8.36244609e-01, 4.30954358e-01, 3.36325080e-01, 4.64812396e-01, + 3.59119545e-01, 4.46583657e-01, 4.11849902e-01, 7.91683705e-01, + 9.05923969e-01, 9.78355471e-01, 6.00500903e-01, 6.58112732e-01, + 9.82635217e-01, 5.17340547e-01, 2.80000378e-01, 9.73667686e-02, + 7.02810620e-01, 2.36811151e-01, 3.72802331e-01, 6.13680212e-01, + 8.59358537e-01, 7.07611548e-01, 1.25129327e-01, 6.19772362e-01, + 1.75676032e-01, 4.61162472e-01, 8.86568485e-01, 5.44900181e-01, + 5.43623344e-01, 5.99687827e-01, 6.05290895e-01, 9.55831196e-01, + 7.43341490e-01, 1.21098972e-01, 1.72510401e-01, 6.75851447e-01, + 8.05463584e-01, 4.90538976e-02, 5.79412266e-01, 9.46759569e-01, + 2.25075578e-01, 9.72467123e-01, 8.82391429e-01, 6.36069484e-01, + 2.62940963e-01, 5.39028357e-01, 7.97688315e-01, 6.92736261e-01, + 9.04445568e-01, 1.17347367e-01, 9.74424315e-01, 6.86943402e-01, + 2.55646187e-01, 8.10824021e-01, 3.77618845e-02, 4.54739412e-01, + 1.30133574e-01, 8.64149700e-01, 3.36050621e-01, 5.20979198e-01, + 1.06564453e-01, 8.25132673e-01, 3.24691291e-01, 5.68278962e-01, + 9.96891990e-03, 2.53055416e-01, 6.92810702e-02, 5.73506182e-01, + 5.98755884e-01, 2.70908536e-01, 1.16946732e-01, 9.00115871e-01, + 8.99171023e-01, 1.49706602e-01, 9.90410630e-01, 5.52884767e-01, + 2.23368805e-01, 4.24984034e-01, 3.15279787e-01, 4.02863385e-01, + 1.32490132e-01, 6.12507969e-01, 7.75470470e-01, 3.03788987e-01, + 8.09816938e-01, 5.51244819e-02, 5.57184003e-01, 4.78323230e-01, + 3.16198852e-01, 4.37246245e-02, 2.00394780e-01, 2.07153216e-01, + 4.35360023e-01, 3.27049535e-03, 5.88090443e-01, 9.87310631e-01, + 4.48000309e-01, 8.26970379e-01, 9.63004400e-01, 5.28054977e-01, + 2.31469302e-01, 8.16195404e-01, 1.11114151e-01, 8.76980575e-01, + 8.79745589e-01, 4.07336830e-01, 7.53084034e-01, 3.42539389e-01, + 4.10135264e-01, 5.49545791e-01, 8.61324025e-02, 9.63889143e-01, + 6.74782766e-01, 1.57750849e-01, 3.69064150e-01, 2.02781018e-01, + 8.98577037e-01, 5.91808176e-02, 4.44658234e-01, 5.09630377e-01, + 8.63433396e-01, 8.07552583e-01, 4.61586958e-01, 3.88508684e-01, + 8.55963808e-01, 1.59259234e-01, 5.67096453e-01, 6.45100269e-01, + 4.23739705e-01, 2.36566610e-01, 5.88852233e-01, 1.42456888e-01, + 6.09449063e-01, 2.91932431e-01, 2.15341330e-01, 8.10063767e-01, + 7.30277737e-01, 5.68174445e-01, 2.26578155e-02, 1.75666393e-02, + 7.42347746e-01, 2.34091828e-01, 9.93016145e-01, 3.71463380e-01, + 5.37628998e-01, 5.15323678e-01, 9.28717897e-01, 3.75234961e-01, + 6.42269116e-01, 2.58183825e-01, 9.39492562e-01, 1.68855727e-02, + 1.46790998e-01, 4.44304313e-01, 8.27096789e-01, 9.65983613e-01, + 6.23461705e-01, 4.62219822e-01, 5.03252364e-01, 9.77850835e-01, + 4.21407294e-01, 7.99087692e-01, 4.24821042e-01, 2.17062611e-01, + 6.03106161e-01, 2.96861607e-01, 8.30823608e-01, 1.95787157e-01, + 6.30261220e-01, 4.78713679e-01, 1.46507778e-01, 3.81508909e-01, + 9.25811504e-01, 6.87689757e-01, 6.54612475e-01, 2.43462597e-01, + 6.85728968e-01, 8.65893047e-01, 1.72877918e-01, 3.09501218e-02, + 8.55966506e-01, 9.34467720e-01, 8.35867579e-02, 3.88607159e-01, + 9.15155385e-01, 6.58913765e-01, 2.42180137e-01, 2.46684840e-01, + 6.36678590e-01, 4.74446255e-01, 9.26442388e-01, 7.82513307e-01, + 3.26607167e-01, 2.56176734e-01, 7.66614295e-01, 3.58891060e-01, + 6.57769693e-01, 9.10220435e-01, 7.69488588e-01, 7.40670425e-01, + 1.71742490e-01, 3.58707520e-01, 6.69410941e-01, 3.46724171e-01, + 2.24290351e-01, 5.53622957e-01, 9.37881088e-01, 5.99370135e-01, + 8.32153059e-01, 7.07144882e-01, 5.76510777e-01, 6.13860514e-01, + 8.69925240e-01, 9.04260751e-01, 7.17822873e-01, 9.41333028e-01, + 9.77852344e-02, 3.10661266e-01, 9.06719929e-01, 4.41852355e-01, + 2.87260615e-01, 4.65262943e-01, 8.51225292e-01, 1.95858580e-01, + 4.60642027e-01, 6.07634181e-01, 8.58294303e-01, 7.04950942e-01, + 3.18351000e-01, 7.04083103e-01, 7.54832971e-01, 2.28850922e-01, + 9.65221365e-01, 1.65974800e-01, 3.33757588e-01, 7.63917161e-01, + 7.95931786e-01, 1.25451562e-01, 9.20205666e-01, 6.93588360e-01, + 2.07615294e-01, 3.67905817e-01, 2.84161666e-01, 8.20995283e-01, + 2.33326835e-01, 4.72732003e-01, 5.37092693e-01, 8.00556071e-01, + 5.66400893e-01, 1.00017828e-01, 3.77833077e-01, 6.18122571e-01, + 8.88109779e-01, 7.06298775e-01, 2.38202240e-01, 8.78992198e-01, + 7.37780946e-01, 3.67454915e-01, 7.89792206e-02, 3.79873213e-02, + 7.56798927e-02, 8.75369367e-01, 9.39321223e-01, 7.85939325e-01, + 4.08066159e-02, 2.12340053e-01, 7.69471008e-01, 1.74381287e-01, + 1.60841016e-01, 7.72649803e-01, 8.16524393e-02, 9.03926140e-01, + 7.65933215e-01, 2.38672182e-01, 2.99578900e-02, 2.47778312e-02, + 7.96387666e-02, 7.15959981e-01, 5.31452267e-01, 1.21193992e-01, + 9.05560889e-01, 7.56699236e-02, 1.00237568e-01, 6.04340484e-01, + 3.41526161e-01, 8.75333335e-02, 5.68548728e-01, 3.21788914e-01, + 9.56745416e-01, 3.71181926e-01, 2.76248909e-01, 9.92589721e-01, + 1.42920537e-01, 7.48649341e-01, 8.43028090e-01, 4.29391774e-01, + 4.38819469e-01, 9.50800680e-01, 4.72544801e-02, 5.66026696e-01, + 7.22736005e-01, 5.04268996e-01, 6.57853778e-01, 9.61713826e-01, + 8.95523497e-01, 3.34435877e-01, 8.97264821e-01, 5.64684560e-01, + 1.99838647e-01, 9.60683345e-01, 7.92005704e-01, 3.23132314e-01, + 5.07424603e-01, 5.28305189e-01, 1.21013320e-01, 7.70779091e-01, + 1.29072351e-01, 1.45333366e-01, 1.40539434e-01, 2.95840404e-01, + 7.65696290e-01, 8.05248438e-01, 1.91378861e-01, 6.25523103e-01, + 8.83920163e-01, 6.55328273e-01, 6.90872602e-01, 3.44399040e-01, + 4.02787192e-01, 9.98515178e-01, 9.64001652e-01, 5.27608302e-01, + 4.22985376e-01, 6.45137599e-01, 2.64982564e-01, 3.55932607e-02, + 1.56578365e-02, 8.94011735e-01, 6.60009637e-01, 4.63266413e-01, + 9.17174867e-01, 5.74679175e-01, 3.80381277e-01, 5.30344006e-01, + 9.16629424e-01, 8.96553125e-01, 9.88238713e-01, 9.71032691e-01, + 6.61241205e-01, 2.53430771e-01, 2.66687645e-01, 2.20269105e-01, + 8.71755269e-01, 3.34287811e-01, 7.18603753e-01, 2.46970751e-01, + 5.89249037e-01, 7.00068234e-01, 6.89398030e-02, 2.33212759e-01, + 8.37047068e-01, 4.55746642e-01, 3.13376759e-01, 3.36671744e-01, + 9.86266611e-01, 4.91239814e-01, 3.08574122e-02, 7.94701934e-01, + 5.66491704e-01, 7.67457763e-01, 9.37298891e-01, 4.78976448e-01, + 9.86544042e-01, 7.02061268e-01, 6.53817701e-01, 3.71155276e-01, + 2.60907578e-01, 5.85319640e-01, 9.45041623e-01, 7.40462655e-01, + 1.11546526e-01, 4.10594828e-01, 1.06975855e-01, 3.84593793e-01, + 9.77971558e-01, 3.08326986e-01, 8.07310177e-01, 3.28507306e-01, + 9.32904076e-01, 4.90315230e-01, 1.88473389e-01, 9.98211022e-01, + 2.00129754e-01, 8.39642213e-01, 7.65678274e-01, 1.80968461e-01, + 5.43392463e-01, 6.61209029e-01, 8.98463227e-02, 9.67827931e-01, + 1.69588308e-01, 2.52317843e-01, 6.71753608e-01, 5.29174070e-01, + 4.90966173e-01, 7.95859952e-01, 8.47774974e-01, 9.90356217e-01, + 7.17803992e-02, 5.01820617e-01, 4.78503791e-01, 1.72398291e-01, + 8.58030440e-01, 3.91881377e-01, 5.05400976e-01, 3.47302950e-01, + 8.97706444e-01, 1.47047957e-01, 1.09276728e-01, 3.85948120e-01, + 6.32160799e-01, 3.09729769e-01, 1.45959889e-01, 6.51738192e-01, + 2.77359906e-01, 6.92773054e-01, 8.14352970e-01, 8.96188714e-01, + 2.39638765e-01, 8.63710492e-01, 1.66139586e-01, 6.03744055e-01, + 1.24088509e-01, 9.15337173e-01, 3.24991685e-01, 6.60493009e-02, + 1.09817591e-01, 8.07880695e-01, 9.71810173e-01, 4.25945929e-01, + 1.20525605e-02, 5.16411392e-01, 2.68513580e-01, 9.24923249e-01, + 4.32181559e-01, 9.68089042e-01, 3.81282468e-01, 4.62766764e-01, + 5.44815631e-01, 8.62732384e-01, 2.15997007e-01, 8.37078836e-01, + 1.66759570e-01, 6.02925213e-01, 4.09434973e-01, 7.82767163e-01, + 8.17678578e-01, 3.35119919e-01, 9.73108659e-01, 9.44013792e-01, + 3.52023720e-02, 2.37726578e-01, 9.08003444e-02, 3.94729051e-01, + 4.66562025e-01, 9.58716767e-01, 9.51111004e-02, 9.03067834e-02, + 9.67253250e-01, 1.34958150e-01, 7.75408263e-01, 2.41508660e-01, + 4.44066115e-01, 8.03780035e-01, 3.31793361e-01, 2.92949631e-01, + 3.84433947e-02, 1.57765046e-01, 1.14735394e-01, 8.39733854e-01, + 7.53977626e-02, 3.78325908e-01, 6.16541477e-01, 2.15293843e-01, + 8.34179433e-01, 3.35038491e-01, 4.71613667e-01, 1.13641679e-01, + 1.61295492e-02, 3.26335647e-01, 5.18397775e-01, 5.61656625e-01, + 4.42681186e-01, 3.02317784e-01, 4.59098700e-01, 4.98011038e-01, + 5.48420488e-01, 2.71047389e-01, 3.06884911e-01, 4.76432724e-01, + 3.64307976e-01, 6.69453523e-01, 8.54892855e-01, 4.92702524e-01, + 1.65759921e-01, 9.45461863e-01, 3.75407124e-01, 7.01633745e-01, + 7.32011928e-01, 9.00117458e-01, 5.35411379e-01, 5.61215090e-01, + 9.54729047e-01, 3.18383819e-01, 7.93318688e-01, 8.83019804e-01, + 6.70023448e-01, 3.04276026e-01, 7.72705160e-01, 1.16462235e-01, + 6.11836183e-01, 5.59790131e-01, 5.53714370e-01, 8.51134658e-01, + 6.33641310e-01, 9.08476844e-01, 1.18270140e-01, 3.55683184e-01, + 3.24686131e-01, 7.62193842e-01, 9.52641604e-01, 5.31009229e-02, + 6.00007976e-01, 6.18481943e-01, 3.89081395e-01, 7.25332074e-01, + 3.70882927e-01, 9.88628705e-01, 8.41353168e-01, 4.00406070e-01, + 4.23043795e-01, 7.36063541e-01, 9.72860479e-01, 1.36609972e-01, + 6.44853627e-01, 5.47117840e-01, 4.08717930e-01, 5.44742362e-01, + 9.86351244e-01, 9.97193796e-01, 2.48848748e-01, 6.77861375e-01, + 6.89598269e-01, 9.26310921e-01, 8.52964325e-02, 7.94844855e-01, + 6.32468893e-01, 7.97472368e-01, 4.90493449e-02, 8.54016131e-02, + 5.30757552e-01, 6.71426051e-01, 6.13413818e-01, 5.30918505e-01, + 2.94998400e-01, 1.16854328e-01, 2.89631219e-01, 8.93798771e-01, + 6.06916939e-01, 6.34586972e-01, 8.04901103e-01, 8.02330018e-01, + 7.79161920e-01, 8.19051757e-02, 8.94049903e-01, 2.21494005e-01, + 7.98238830e-01, 8.98699013e-01, 4.24380388e-01, 8.32058631e-01, + 1.13005616e-01, 2.43128336e-01, 5.76537456e-01, 1.21295230e-01, + 4.40471214e-01, 9.10894263e-02, 4.63586749e-01, 1.54430311e-01, + 1.52645291e-01, 9.30308029e-01, 2.59722999e-01, 9.36238982e-01, + 6.66003428e-01, 4.20867757e-01, 2.63315470e-02, 4.68727306e-01, + 8.50890717e-01, 8.97461649e-02, 5.08052130e-01, 3.43861376e-01, + 6.27334974e-01, 8.00342743e-01, 4.73994538e-01, 9.58824933e-01, + 3.67167179e-01, 3.19473500e-01, 5.74331025e-01, 8.15212512e-01, + 8.76944579e-01, 2.62598053e-01, 9.55549952e-01, 1.84390110e-01, + 2.33745334e-01, 1.37922140e-01, 7.59530653e-01, 5.15519280e-01, + 5.82319374e-01, 4.09600826e-02, 8.48185616e-01, 5.27773620e-01, + 4.03515531e-01, 2.49546221e-01, 2.98413460e-01, 2.67321780e-01, + 9.83392883e-01, 1.65392749e-01, 2.54257615e-01, 8.03826748e-01, + 2.70193424e-01, 6.08416784e-01, 5.68371411e-02, 5.84520953e-01, + 5.32395063e-01, 4.06089193e-01, 6.76055824e-01, 8.15386503e-01, + 9.78666220e-01, 4.56107596e-01, 1.00136326e-01, 1.46995741e-01, + 2.67153710e-01, 6.13216652e-01, 1.50174198e-01, 9.06924786e-01, + 5.21420408e-01, 5.69244153e-01, 4.99491059e-01, 5.36596230e-01, + 5.20118606e-01, 2.75962708e-01, 6.62795103e-01, 6.16208160e-01, + 1.13864251e-01, 2.53682004e-01, 6.23642088e-01, 8.98394418e-01, + 6.43753008e-01, 7.31750809e-01, 1.56984479e-01, 4.40223144e-01, + 2.28920095e-01, 1.26804167e-01, 2.20281989e-01, 1.98547324e-01, + 3.20564984e-01, 2.21365943e-02, 2.21559477e-01, 7.42704049e-01, + 3.85612736e-01, 3.14809258e-01, 7.86060555e-01, 5.11447151e-01, + 8.41784475e-01, 5.59739247e-02, 1.62071758e-01, 8.69973637e-01, + 7.40171035e-01, 3.56223266e-01, 4.51027937e-01, 7.18955818e-01, + 5.55427487e-01, 1.39307159e-01, 2.03444834e-01, 5.67147572e-01, + 5.57513418e-01, 6.68842995e-01, 6.34503555e-01, 8.51115981e-01, + 1.30121768e-01, 4.39452406e-01, 6.51566025e-01, 4.30033735e-02, + 4.53622277e-01, 4.00969361e-01, 3.35681361e-01, 1.91029700e-01, + 8.94004702e-01, 4.72818707e-01, 6.43628049e-01, 7.74350225e-01, + 1.16116751e-01, 4.03800048e-01, 1.65561265e-01, 3.90710462e-02, + 3.11661710e-01, 1.53820919e-01, 9.71715921e-01, 6.66384485e-01, + 9.72690165e-01, 2.61938693e-01, 8.29244113e-01, 5.87743977e-03, + 3.47437760e-01, 2.81038913e-01, 9.43336660e-01, 4.22115291e-01, + 5.51480637e-02, 8.37854573e-01, 1.57179652e-02, 7.93045574e-02, + 5.57851326e-01, 6.96702009e-01, 2.86106747e-01, 8.23801131e-01, + 3.63651770e-01, 1.37242347e-02, 4.48045206e-01, 3.52525589e-01, + 7.69569691e-01, 6.86002139e-01, 7.69509966e-01, 3.44147593e-01, + 1.81635039e-01, 5.63247242e-01, 5.59495601e-01, 2.25528428e-01, + 5.17906955e-01, 5.39830628e-01, 9.77978851e-01, 1.28756923e-01, + 6.21543235e-01, 7.60604574e-01, 7.12956305e-01, 3.28861045e-01, + 6.07457612e-01, 8.17584800e-01, 2.58073899e-01, 2.71478889e-01, + 6.90569169e-01, 3.04929366e-01, 3.21495094e-01, 9.31576852e-01, + 7.76784069e-01, 4.83600053e-01, 6.60327979e-02, 2.36839578e-01, + 6.47323092e-01, 3.38791142e-01, 2.25976904e-01, 4.60322008e-01, + 7.91324886e-02, 5.68111985e-02, 9.68530371e-01, 9.03778030e-01, + 6.72483063e-01, 5.36745941e-01, 2.70638711e-01, 6.34570643e-01, + 6.24602692e-01, 1.16697301e-01, 2.64656305e-01, 2.36728403e-01, + 9.35274164e-01, 7.38961910e-02, 7.53428548e-02, 6.98464754e-01, + 6.04746161e-02, 5.85141483e-01, 5.49635035e-01, 3.59332528e-01, + 1.32046694e-01, 5.87671170e-01, 4.95754754e-01, 8.95385235e-01, + 3.13310068e-01, 1.06790548e-01, 5.88620743e-01, 8.57553634e-01, + 9.98100562e-01, 4.38280375e-01, 2.09730992e-01, 6.93059723e-01, + 6.32903971e-01, 5.17114267e-01, 8.73673332e-02, 2.39260365e-01, + 9.50826048e-01, 7.09171327e-01, 9.13340881e-01, 7.31244958e-01, + 5.58105885e-01, 7.63020105e-01, 1.80168672e-01, 6.64540527e-01, + 4.40438267e-01, 6.86114371e-01, 7.28113485e-01, 9.31472446e-01, + 4.70326358e-01, 3.89769582e-01, 4.53731736e-01, 1.90862675e-01, + 7.88358001e-01, 9.03167120e-01, 2.89049311e-02, 8.19188726e-01, + 1.00671977e-01, 6.48859926e-01, 7.66033464e-01, 4.90798051e-01, + 2.92120329e-02, 8.85040531e-01, 9.50276272e-01, 6.59853538e-01, + 6.87781041e-01, 4.72308452e-01, 3.48310805e-01, 5.16752029e-01, + 3.30939823e-01, 9.34661495e-01, 8.84183554e-01, 5.64139545e-01, + 3.71589673e-02, 7.90825320e-01, 3.24254340e-02, 1.03112129e-01, + 6.24809200e-01, 6.61016549e-01, 8.30842454e-01, 6.48075177e-01, + 1.63824068e-01, 1.80501894e-01, 2.69806743e-02, 7.97901562e-01, + 8.73214578e-01, 8.23781455e-02, 4.41077184e-01, 8.14281744e-01, + 8.38220372e-01, 7.11401445e-01, 9.98388075e-02, 8.32266347e-01, + 7.50407546e-01, 5.18934011e-01, 2.36028627e-02, 7.23147252e-01, + 1.09822401e-01, 5.41577941e-01, 7.07603390e-01, 8.38653795e-01, + 8.72934973e-01, 1.61208532e-01, 4.37979942e-02, 8.05917472e-01, + 1.70862226e-01, 6.68061745e-01, 7.23535495e-01, 6.55255428e-01, + 3.79277224e-01, 2.42366650e-01, 3.11588703e-01, 9.54839971e-01, + 7.19243773e-01, 3.11043858e-01, 5.73941494e-01, 8.50660378e-01, + 9.54982580e-03, 8.61089449e-01, 9.25997967e-01, 7.18995698e-01, + 8.48294256e-01, 4.62163126e-01, 8.28878010e-01, 9.40533542e-01, + 4.12123917e-01, 6.52866417e-02, 8.48171677e-01, 1.66818093e-01, + 7.22151560e-01, 4.09911346e-01, 9.40170702e-01, 8.40881727e-01, + 3.15975146e-01, 9.04856631e-01, 8.61597915e-01, 2.98573826e-01, + 2.93275893e-01, 7.39686037e-01, 9.16749149e-01, 8.64959196e-01, + 1.14782190e-01, 6.25620140e-01, 9.66841982e-01, 2.45214207e-01, + 1.82117343e-01, 6.78560130e-02, 9.13602911e-01, 3.18439999e-01, + 1.17489861e-01, 8.37738634e-01, 6.88803817e-01, 3.72079384e-01, + 9.81933370e-01, 6.25610523e-01, 6.34913442e-01, 6.37501490e-01, + 9.55689526e-01, 1.04286618e-01, 6.23448846e-01, 9.30493165e-02, + 7.08930185e-01, 5.97449025e-01, 3.21924112e-01, 2.07761517e-01, + 3.00325347e-01, 6.69578674e-01, 5.29394366e-01, 9.24879076e-01, + 7.11409192e-01, 1.77027117e-01, 9.06776058e-01, 2.26962776e-01, + 2.05829972e-01, 5.94427570e-01, 5.09323369e-01, 9.18138337e-01, + 7.80423501e-01, 6.78083818e-01, 9.53799881e-01, 6.99541127e-01, + 7.75430765e-01, 7.08234647e-01, 1.18675152e-01, 9.76904826e-01, + 2.51768126e-01, 5.86829970e-01, 7.20266785e-01, 6.61479327e-01, + 1.76079575e-01, 3.39683818e-01, 8.97698030e-01, 7.22314888e-01, + 3.29057090e-01, 9.73537738e-01, 7.69182537e-01, 7.25195101e-01, + 5.39294909e-01, 9.14759990e-01, 7.05701592e-01, 3.64908013e-02, + 1.64869704e-01, 1.65961009e-02, 3.32424967e-02, 5.47289496e-01, + 5.70394494e-01, 8.03394182e-01, 8.37832155e-01, 8.93858503e-01, + 3.70406151e-01, 9.71684676e-01, 9.84638158e-01, 8.16090310e-01, + 3.52964409e-01, 2.26780945e-01, 5.34103288e-01, 7.57007027e-01, + 2.48122510e-01, 6.52326815e-01, 3.63498094e-01, 7.32110131e-01, + 9.17774053e-01, 8.88846797e-01, 6.86428183e-01, 7.32652603e-01, + 5.95586080e-01, 8.39563793e-01, 8.26122318e-01, 3.66732098e-01, + 8.25373209e-01, 2.80269431e-01, 1.38494853e-01, 2.70283618e-01, + 7.92609090e-01, 7.95120398e-01, 5.86164837e-01, 2.32304473e-01, + 4.23520411e-01, 6.00331206e-01, 9.47899638e-01, 7.83849206e-01, + 9.09825293e-02, 1.48691470e-01, 4.31205796e-01, 2.86079763e-01, + 9.05188382e-01, 3.12373838e-01, 8.81830708e-01, 1.13861123e-01, + 4.33651514e-01, 7.76116989e-03, 6.54689548e-01, 8.95913326e-02, + 2.00499612e-01, 6.24586410e-01, 7.49943935e-01, 2.17308870e-01, + 8.81175198e-01, 9.51923552e-01, 8.28504768e-01, 3.36433124e-01, + 1.26263169e-01, 3.70242060e-01, 8.29145642e-01, 6.20793064e-01, + 6.30890711e-02, 4.74349619e-03, 4.94081018e-01, 3.44532663e-01, + 6.96904582e-02, 2.90926003e-01, 6.06143663e-01, 7.47535614e-01, + 3.42266526e-01, 4.67872881e-01, 4.81118884e-01, 7.41796303e-01, + 7.46412947e-02, 1.52662173e-02, 9.70259944e-01, 7.86156229e-01, + 5.81743012e-01, 3.03130443e-01, 6.46081571e-02, 3.14974196e-01, + 6.93277960e-01, 8.32261271e-02, 6.96308407e-01, 6.40907926e-01, + 2.45965091e-01, 7.09653017e-01, 2.28339380e-01, 1.21844492e-01, + 6.78876752e-01, 2.02368003e-01, 7.93857283e-01, 7.95545403e-02, + 6.62529991e-01, 4.14764518e-01, 9.65061340e-01, 4.64787127e-01, + 8.00736722e-01, 4.58155481e-01, 7.97360280e-01, 5.03906327e-01, + 3.70894338e-01, 7.62966412e-01, 3.41887723e-02, 3.28877376e-01, + 9.48152230e-01, 6.14377987e-01, 8.31598857e-01, 4.02787771e-01, + 7.89170122e-01, 6.16831973e-01, 8.82136733e-01, 6.51538121e-01, + 3.40828301e-03, 1.32384245e-01, 3.40397288e-01, 6.47307330e-01, + 3.20716817e-01, 6.91273248e-01, 5.41961787e-01, 4.89032995e-01, + 7.71502962e-01, 5.70432391e-01, 7.59325490e-01, 8.48202327e-01, + 3.04159605e-01, 4.48849226e-01, 1.67951797e-01, 2.27212712e-01, + 6.83528832e-01, 7.25063393e-01, 9.93452424e-01, 2.62273404e-01, + 4.93810104e-01, 5.23750223e-01, 1.91858569e-01, 4.35240695e-02, + 1.97876990e-01, 3.29177471e-01, 3.04972488e-04, 8.33490954e-01, + 5.23238694e-01, 4.46638340e-01, 2.71284859e-01, 4.19057103e-01, + 1.21724201e-01, 8.27791414e-01, 7.21628294e-01, 9.19986812e-01, + 9.35140750e-01, 3.75794944e-01, 9.56673021e-01, 6.49316296e-01, + 8.52679545e-01, 4.52986925e-01, 8.65245637e-01, 3.61151812e-01, + 8.83369213e-01, 6.23015849e-01, 8.80019975e-01, 9.71597400e-01, + 8.03321907e-01, 4.58589982e-01, 9.70689575e-01, 5.88408087e-01, + 2.67446801e-02, 2.26081080e-01, 3.72502710e-01, 5.18017729e-01, + 6.97848301e-01, 1.11533833e-02, 1.15989123e-01, 5.73253222e-02, + 6.15797763e-01, 4.36061694e-01, 1.32861084e-01, 6.51307912e-01, + 9.65943445e-01, 9.46475591e-01, 9.44260602e-01, 2.94840118e-01, + 1.88560924e-01, 6.77128258e-01, 9.52484675e-01, 1.33865981e-01, + 8.54146793e-01, 8.90577957e-02, 2.11491058e-01, 9.35210260e-02, + 5.26777010e-01, 6.56970772e-01, 5.85237862e-01, 1.75293799e-01, + 2.38045167e-01, 7.04148978e-02, 9.06796119e-01, 6.59266858e-01, + 1.80639432e-01, 7.95717345e-01, 4.56240189e-01, 3.81653268e-01, + 6.05633362e-01, 8.32495907e-01, 1.59136315e-01, 7.95481552e-01, + 9.46817864e-01, 9.47791652e-01, 5.05922343e-01, 6.77495961e-01, + 9.78010337e-01, 1.37835768e-01, 6.82173898e-01, 3.29347815e-01, + 9.50828687e-01, 7.23507361e-02, 2.09540106e-02, 5.61469640e-01, + 2.69103741e-01, 4.50867628e-01, 9.68220376e-01, 9.00338277e-01, + 1.11610400e-01, 5.38335967e-01, 1.74701649e-01, 8.64694365e-01, + 1.89753336e-01, 7.95222604e-02, 3.01202421e-02, 3.13545816e-01, + 8.06559078e-01, 6.38338768e-02, 7.46182571e-01, 6.25119320e-01, + 5.41727273e-01, 6.76925185e-01, 9.60211713e-01, 2.65303850e-01, + 8.71288685e-02, 9.87959272e-01, 2.33741328e-01, 3.43865754e-01, + 6.87328898e-01, 5.08280716e-01, 6.44323047e-01, 2.12316663e-01, + 6.95363966e-01, 7.43354605e-01, 9.86640432e-01, 1.93662218e-01, + 4.51918040e-01, 6.98536368e-01, 4.27234418e-01, 3.18267987e-01, + 7.23525475e-01, 6.37590551e-01, 7.56891147e-01, 1.12875351e-01, + 5.43071437e-01, 5.67604800e-01, 8.69433810e-01, 4.22249989e-01, + 9.21198255e-02, 3.54702740e-01, 6.84999683e-01, 8.16958028e-01, + 4.06961846e-01, 1.18200063e-01, 1.23469628e-01, 7.21167252e-01, + 2.71046415e-01, 3.36668549e-01, 3.97949914e-01, 7.42482378e-01, + 7.47981401e-01, 7.78112282e-01, 7.30924456e-01, 6.59854796e-01, + 1.03592459e-01, 6.75703864e-01, 5.70338460e-01, 6.79150944e-01, + 6.69903770e-01, 3.82185660e-01, 8.31238061e-01, 2.59920340e-01, + 4.30541218e-01, 1.81508574e-01, 8.12640025e-03, 4.77909754e-01, + 9.53608622e-01, 2.97678037e-01, 2.74910037e-01, 2.02071748e-01, + 8.30354579e-01, 3.53941366e-01, 6.98485636e-01, 9.48972263e-01, + 1.02703365e-01, 3.31339850e-01, 7.91926857e-01, 5.86240067e-02, + 5.15643169e-01, 2.33328945e-01, 5.11936388e-01, 3.01053825e-01, + 9.32559125e-01, 5.52791125e-01, 5.56256708e-02, 2.33923262e-02, + 4.20381337e-01, 9.33832824e-01, 2.53670976e-01, 9.69247613e-02, + 7.36729781e-01, 6.31738973e-02, 9.71696339e-01, 8.01241562e-01, + 3.09146300e-01, 6.85179246e-01, 5.74895308e-01, 3.33924642e-01, + 8.68068076e-01, 2.39791146e-01, 8.04124546e-01, 2.45866254e-01, + 8.72816537e-01, 2.56117437e-01, 7.59241929e-01, 1.75999550e-01, + 7.17279236e-01, 1.03176836e-01, 4.40717391e-01, 4.27309182e-01, + 8.69288331e-01, 6.96183932e-01, 3.01024762e-01, 3.57350611e-01, + 5.52794409e-01, 4.93132601e-01, 5.09546441e-01, 6.84150057e-01, + 3.79250310e-01, 3.76902888e-01, 5.98274291e-01, 8.05906253e-01, + 3.77474176e-01, 9.00157802e-01, 6.66988939e-01, 5.23412136e-01, + 2.86820270e-01, 7.81255742e-01, 8.56514003e-01, 2.37522131e-01, + 1.79874039e-01, 1.42103574e-01, 5.27416220e-01, 7.55706133e-01, + 9.43644544e-01, 1.14794332e-01, 9.17943949e-01, 1.71947052e-01, + 1.03421052e-01, 7.09183034e-01, 6.24529802e-01, 9.91979882e-01, + 4.57969737e-01, 1.06292360e-01, 7.54458210e-01, 6.89607757e-01, + 4.57445849e-01, 6.95306056e-01, 5.43155295e-01, 9.71219157e-01, + 4.61575550e-01, 5.34795171e-01, 8.58721491e-01, 8.92932864e-01, + 1.37488682e-01, 4.03353217e-01, 9.61973999e-02, 2.38900357e-01, + 2.23009993e-01, 4.81163975e-01, 3.18089770e-01, 8.46441974e-01, + 7.61390313e-01, 6.98668535e-01, 9.87180329e-01, 5.43150576e-01, + 5.07675090e-01, 2.42547762e-01, 4.04915929e-01, 7.89859765e-01, + 8.49283774e-01, 6.82575084e-01, 1.75624000e-01, 9.62116402e-01, + 3.54642938e-01, 7.93029168e-01, 6.81483532e-01, 5.82446618e-01, + 3.93532636e-01, 2.32569365e-02, 9.46114319e-01, 5.68364396e-01, + 3.50999775e-01, 4.79305230e-02, 2.88544377e-01, 7.28636898e-01, + 3.11413710e-01, 8.79198378e-01, 8.67337001e-01, 7.99535425e-01, + 2.91198110e-01, 3.01695765e-01, 9.76821106e-01, 5.88110424e-01, + 5.90613357e-01, 7.69730486e-01, 2.83473394e-01, 8.26827146e-01, + 3.16196255e-03, 3.37972141e-01, 9.88618803e-01, 1.39080547e-01, + 7.83144068e-01, 2.88921721e-01, 1.28304874e-02, 6.75349250e-01, + 6.83286179e-01, 4.99916919e-01, 4.97452670e-01, 4.56819263e-01, + 6.79448493e-01, 8.97614699e-01, 2.66447909e-01, 7.86028565e-01, + 7.96762987e-01, 8.85525380e-01, 6.42010678e-01, 6.89314660e-01, + 5.60529219e-01, 3.50510208e-01, 3.54991078e-01, 7.30942246e-01, + 4.90206771e-01, 5.03675702e-01, 4.20625068e-02, 1.60267939e-01, + 3.93979561e-01, 7.98968322e-01, 3.16348656e-01, 2.01832693e-01, + 2.46196473e-01, 9.12775114e-01, 2.05830514e-01, 6.70622277e-01, + 9.55204724e-01, 8.53499621e-01, 4.05659342e-01, 6.42852505e-01, + 7.10368404e-01, 9.85672826e-01, 5.22335610e-01, 6.17257427e-01, + 2.10168749e-01, 3.91883977e-02, 6.23935924e-01, 3.08249153e-01, + 1.48043820e-01, 4.29017962e-01, 3.81915495e-01, 6.64484076e-01, + 5.95697760e-02, 4.49421742e-01, 7.60924114e-02, 2.97092620e-01, + 3.69015418e-01, 1.99398822e-01, 7.13120938e-01, 4.90608942e-01, + 2.55956050e-01, 1.15931804e-01, 2.65739230e-01, 6.95050602e-02, + 2.28148923e-01, 2.53978205e-01, 7.48474937e-01, 4.64114984e-01, + 6.11688110e-01, 1.64176681e-02, 4.28609047e-01, 7.55192971e-01, + 1.91176457e-01, 2.37300686e-01, 5.82715387e-01, 3.26180071e-01, + 4.41388668e-02, 1.50616879e-01, 5.40684117e-01, 1.98670940e-01, + 3.90193589e-01, 2.00872943e-01, 3.96390382e-02, 2.01952262e-01, + 8.65773997e-02, 7.78135413e-01, 5.66935157e-01, 8.54323130e-01, + 6.34795405e-02, 3.02726192e-01, 4.71595156e-01, 9.05002519e-01, + 9.49341119e-01, 4.43354491e-01, 1.74919522e-01, 3.96306576e-01, + 2.34611668e-02, 3.41141240e-01, 6.88332437e-01, 5.93704034e-01, + 9.10742757e-01, 2.47513034e-01, 1.30009404e-01, 4.79380595e-01, + 4.12512105e-01, 5.27279416e-01, 1.21502829e-01, 8.62005619e-01, + 3.94882866e-01, 1.46732491e-02, 7.01567612e-02, 2.26620965e-01, + 3.95324049e-01, 4.41922144e-01, 9.26418841e-01, 1.72320921e-01, + 3.82164306e-01, 7.81638763e-01, 9.18169559e-01, 2.60941703e-01, + 3.41689158e-01, 9.17607008e-01, 8.49148931e-01, 8.74908102e-02, + 1.78918873e-01, 6.41279534e-01, 5.01119448e-01, 1.74456896e-01, + 6.08854366e-01, 5.86400285e-01, 3.74814704e-01, 7.13765690e-02, + 7.94730717e-01, 8.62809856e-01, 3.53704151e-01, 2.34038496e-01, + 4.14507914e-02, 7.05298973e-01, 7.74714979e-01, 5.99646169e-01, + 5.63215482e-01, 2.14126063e-03, 9.48156758e-01, 6.62962461e-01, + 4.76069654e-01, 9.82189519e-01, 6.09958227e-01, 6.26967132e-03, + 3.48775981e-01, 5.22081206e-01, 3.83073392e-01, 7.34956665e-02, + 3.88333573e-01, 1.60664035e-01, 5.09877065e-01, 5.52157733e-01, + 4.31655760e-01, 4.60277098e-01, 3.71647195e-01, 8.07950553e-01, + 3.51371306e-02, 3.47044301e-01, 6.91446218e-01, 7.32118785e-01, + 1.36860717e-01, 6.90275046e-03, 3.29235453e-01, 7.51278882e-01, + 4.30870775e-01, 2.36302227e-01, 3.70297792e-01, 5.99070044e-01, + 1.42759639e-01, 7.51552579e-01, 8.01303595e-01, 6.96139313e-01, + 6.47544758e-01, 7.91415262e-01, 9.08546686e-01, 5.56580572e-01, + 5.43777442e-01, 1.25130376e-01, 4.99283047e-01, 4.75479041e-02, + 7.16442389e-01, 9.16798249e-01, 2.90504379e-01, 7.70952913e-01, + 7.08851028e-01, 9.28349783e-01, 6.99956039e-01, 8.89243871e-01, + 7.12117654e-01, 4.70064596e-01, 7.23101431e-01, 6.02579469e-01, + 2.70879869e-01, 7.55669789e-01, 2.37187622e-01, 9.99421496e-01, + 2.17781018e-01, 3.03285437e-02, 9.69635771e-01, 1.70569973e-01, + 8.71286711e-01, 9.27828077e-03, 6.53005352e-01, 3.53159788e-01, + 9.78424850e-01, 3.99576178e-02, 1.60529919e-01, 1.13074361e-01, + 6.33820624e-01, 5.31506945e-01, 4.64256293e-01, 9.58932714e-01, + 7.39209641e-01, 8.50208553e-01, 8.17003515e-01, 2.33737166e-01, + 5.18528745e-01, 3.01821746e-01, 1.76899400e-01, 1.32706376e-01, + 9.54769058e-01, 6.33002388e-01, 2.04246835e-01, 1.72337354e-01, + 4.19794547e-01, 5.05213293e-02, 7.02624190e-01, 1.77560384e-01, + 6.91976575e-01, 5.58037859e-01, 7.57545014e-01, 5.52119118e-01, + 4.50284697e-01, 1.54567048e-01, 2.35593591e-01, 7.93746045e-01, + 5.59623343e-01, 6.56726677e-01, 6.18540185e-02, 5.32813342e-01, + 9.28778636e-01, 1.82237287e-02, 6.94747455e-01, 5.53451075e-01, + 1.17457578e-01, 8.41959465e-02, 4.30655855e-01, 3.18721330e-02, + 8.85510860e-01, 4.07483338e-01, 3.82438196e-01, 9.67492837e-01, + 4.83333659e-01, 3.48289304e-02, 3.28717749e-01, 9.27005757e-01, + 1.86092641e-01, 1.93651424e-01, 7.78158750e-01, 3.43323412e-01, + 8.77499307e-01, 9.13954107e-01, 8.10678527e-03, 5.90758463e-01, + 8.40488738e-01, 3.70162725e-01, 6.49109620e-01, 5.58430028e-01, + 4.88604483e-01, 9.06265106e-01, 6.02380040e-01, 6.90543512e-01, + 3.19062117e-01, 8.15405368e-01, 5.50682479e-01, 6.40259343e-01, + 8.70575420e-01, 5.38149570e-01, 4.21968363e-01, 5.47452828e-01, + 6.16975975e-01, 5.50823415e-01, 8.55618928e-01, 8.22240534e-01, + 3.99101284e-01, 4.90405471e-01, 2.19010106e-01, 1.85975691e-01, + 2.57120897e-01, 2.12485292e-01, 9.93864220e-01, 9.69260739e-01, + 6.93063256e-01, 1.03269401e-01, 9.77334048e-01, 7.53686820e-01, + 1.16905301e-01, 6.00001000e-01, 7.35255088e-01, 4.64102602e-02, + 3.53820642e-01, 2.50878091e-01, 2.37320793e-01, 7.18205684e-01, + 5.23954402e-01, 1.02606800e-01, 3.52420052e-01, 9.15295828e-01, + 8.03228185e-01, 1.88864574e-01, 4.64225071e-02, 2.85621607e-01}; +} +} /* namespaces */ diff --git a/src/core/unit_tests/verlet_ia_test.cpp b/src/core/unit_tests/verlet_ia_test.cpp index f0eec00dde..ce58405203 100644 --- a/src/core/unit_tests/verlet_ia_test.cpp +++ b/src/core/unit_tests/verlet_ia_test.cpp @@ -28,7 +28,8 @@ struct Distance { /* Dummy interaction criterion */ struct VerletCriterion { - bool operator()(Particle const &p1, Particle const &p2, Distance const& d) const { + bool operator()(Particle const &p1, Particle const &p2, + Distance const &d) const { return d.interact; } }; diff --git a/src/core/utils.cpp b/src/core/utils.cpp index 93217090bd..9a27967329 100644 --- a/src/core/utils.cpp +++ b/src/core/utils.cpp @@ -1,5 +1,5 @@ -#include #include "utils.hpp" +#include char *strcat_alloc(char *left, const char *right) { if (!left) { diff --git a/src/core/utils.hpp b/src/core/utils.hpp index 3cffb9cdbc..6c44c28124 100644 --- a/src/core/utils.hpp +++ b/src/core/utils.hpp @@ -33,10 +33,10 @@ #include "utils/math/sqr.hpp" #include "utils/memory.hpp" +#include #include #include #include -#include namespace Utils { /** @@ -74,7 +74,7 @@ template int sgn(T val) { return (T(0) < val) - (val < T(0)); } /** permute an integer array field of size size about permute positions. */ inline void permute_ifield(int *field, int size, int permute) { - if (permute == 0) + if (permute == 0) return; if (permute < 0) permute = (size + permute); @@ -184,8 +184,7 @@ inline void unit_vector(double v[3], double y[3]) { } /** calculates the scalar product of two vectors a nd b */ -template -double scalar(const T1& a, const T2& b) { +template double scalar(const T1 &a, const T2 &b) { double d2 = 0.0; int i; for (i = 0; i < 3; i++) @@ -204,8 +203,7 @@ inline void vector_product(T const &a, U const &b, V &c) { /** rotates vector around axis by alpha */ template -void vec_rotate(const T1& axis, double alpha, const T2& vector, - T3& result) { +void vec_rotate(const T1 &axis, double alpha, const T2 &vector, T3 &result) { double sina, cosa, absa, a[3]; sina = sin(alpha); cosa = cos(alpha); @@ -297,7 +295,7 @@ inline double distance(double pos1[3], double pos2[3]) { * \param pos2 Position two. */ template -inline double distance2(const T1& pos1, const T2& pos2) { +inline double distance2(const T1 &pos1, const T2 &pos2) { return Utils::sqr(pos1[0] - pos2[0]) + Utils::sqr(pos1[1] - pos2[1]) + Utils::sqr(pos1[2] - pos2[2]); } @@ -310,8 +308,7 @@ inline double distance2(const T1& pos1, const T2& pos2) { * \return distance squared */ template -double distance2vec(T1 const pos1, T2 const pos2, - T3& vec) { +double distance2vec(T1 const pos1, T2 const pos2, T3 &vec) { vec[0] = pos1[0] - pos2[0]; vec[1] = pos1[1] - pos2[1]; vec[2] = pos1[2] - pos2[2]; @@ -339,7 +336,7 @@ char *strcat_alloc(char *left, const char *right); /** Computes the area of triangle between vectors P1,P2,P3, * by computing the crossproduct P1P2 x P1P3 and taking the half of its norm */ template -inline double area_triangle(const T1& P1, const T2& P2, const T3& P3) { +inline double area_triangle(const T1 &P1, const T2 &P2, const T3 &P3) { double area; double u[3], v[3], normal[3], n; // auxiliary variables u[0] = P2[0] - P1[0]; // u = P1P2 @@ -356,7 +353,7 @@ inline double area_triangle(const T1& P1, const T2& P2, const T3& P3) { /** Computes the normal vector to the plane given by points P1P2P3 */ template -void get_n_triangle(const T1& p1, const T2& p2, const T3& p3, double *n) { +void get_n_triangle(const T1 &p1, const T2 &p2, const T3 &p3, double *n) { n[0] = (p2[1] - p1[1]) * (p3[2] - p1[2]) - (p2[2] - p1[2]) * (p3[1] - p1[1]); n[1] = (p2[2] - p1[2]) * (p3[0] - p1[0]) - (p2[0] - p1[0]) * (p3[2] - p1[2]); n[2] = (p2[0] - p1[0]) * (p3[1] - p1[1]) - (p2[1] - p1[1]) * (p3[0] - p1[0]); @@ -378,7 +375,8 @@ void get_n_triangle(const T1& p1, const T2& p2, const T3& p3, double *n) { * function with exactly this order. Otherwise you need to check the * orientations. */ template -double angle_btw_triangles(const T1& P1, const T2& P2, const T3& P3, const T4& P4) { +double angle_btw_triangles(const T1 &P1, const T2 &P2, const T3 &P3, + const T4 &P4) { double phi; double u[3], v[3], normal1[3], normal2[3]; // auxiliary variables u[0] = P1[0] - P2[0]; // u = P2P1 @@ -454,7 +452,7 @@ namespace Utils { // cross_product: Calculate the cross product of two vectors // template -void cross_product(const T1& a, const T2& b, T3& c) { +void cross_product(const T1 &a, const T2 &b, T3 &c) { c[0] = a[1] * b[2] - a[2] * b[1]; c[1] = a[2] * b[0] - a[0] * b[2]; c[2] = a[0] * b[1] - a[1] * b[0]; diff --git a/src/core/utils/Accumulator.hpp b/src/core/utils/Accumulator.hpp index 5362ef35e9..328269fc4d 100644 --- a/src/core/utils/Accumulator.hpp +++ b/src/core/utils/Accumulator.hpp @@ -52,15 +52,15 @@ inline void Accumulator::operator()(const std::vector &data) { return {d, 0.0}; }); } else { - std::transform( - m_acc_data.begin(), m_acc_data.end(), data.begin(), m_acc_data.begin(), - [this](AccumulatorData &a, - double d) -> AccumulatorData { - auto const old_mean = a.mean; - auto const new_mean = old_mean + (d - old_mean) / m_n; - auto const new_m = a.m+(d-old_mean)*(d-new_mean); - return {new_mean, new_m}; - }); + std::transform(m_acc_data.begin(), m_acc_data.end(), data.begin(), + m_acc_data.begin(), + [this](AccumulatorData &a, + double d) -> AccumulatorData { + auto const old_mean = a.mean; + auto const new_mean = old_mean + (d - old_mean) / m_n; + auto const new_m = a.m + (d - old_mean) * (d - new_mean); + return {new_mean, new_m}; + }); } } @@ -72,33 +72,35 @@ inline std::vector Accumulator::get_mean() const { return res; } - inline std::vector Accumulator::get_variance() const { std::vector res; - if(m_n==1){ - res=std::vector(m_acc_data.size(),std::numeric_limits::max()); + if (m_n == 1) { + res = std::vector(m_acc_data.size(), + std::numeric_limits::max()); } else { - std::transform(m_acc_data.begin(), m_acc_data.end(), std::back_inserter(res), - [this](const AccumulatorData &acc_data) { - return acc_data.m/(static_cast(m_n)-1); //numerically stable sample variance, see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance - }); + std::transform( + m_acc_data.begin(), m_acc_data.end(), std::back_inserter(res), + [this](const AccumulatorData &acc_data) { + return acc_data.m / + (static_cast(m_n) - + 1); // numerically stable sample variance, see + // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance + }); } return res; } /** -returns the standard error of the mean of uncorrelated data. if data are correlated the correlation time needs to be known... +returns the standard error of the mean of uncorrelated data. if data are +correlated the correlation time needs to be known... */ inline std::vector Accumulator::get_std_error() const { - auto const variance=get_variance(); - std::vector std_error(variance.size()); - std::transform(variance.begin(), variance.end(), std_error.begin(), - [this](double d) { - return std::sqrt(d/m_n); - }); - return std_error; + auto const variance = get_variance(); + std::vector std_error(variance.size()); + std::transform(variance.begin(), variance.end(), std_error.begin(), + [this](double d) { return std::sqrt(d / m_n); }); + return std_error; } - } #endif diff --git a/src/core/utils/Cache.hpp b/src/core/utils/Cache.hpp index 5a6d7874d2..f62da7174c 100644 --- a/src/core/utils/Cache.hpp +++ b/src/core/utils/Cache.hpp @@ -138,7 +138,8 @@ template class Cache { * into the cache. */ template - KeyInputIterator put(KeyInputIterator kbegin, KeyInputIterator kend, ValueInputIterator vbegin) { + KeyInputIterator put(KeyInputIterator kbegin, KeyInputIterator kend, + ValueInputIterator vbegin) { auto const range_len = std::distance(kbegin, kend); auto const len = (range_len > max_size()) ? max_size() : range_len; kend = std::next(kbegin, len); @@ -148,7 +149,7 @@ template class Cache { drop_random_element(); } - while(kbegin != kend) { + while (kbegin != kend) { put(*kbegin++, *vbegin++); } diff --git a/src/core/utils/Histogram.hpp b/src/core/utils/Histogram.hpp index 1a4f50541d..1083fd835d 100644 --- a/src/core/utils/Histogram.hpp +++ b/src/core/utils/Histogram.hpp @@ -28,7 +28,6 @@ #include #include - namespace Utils { inline size_t calculate_bin_index(double value, double bin_size, @@ -79,8 +78,9 @@ inline void unravel_index(const int *const len_dims, const int ndims, * \return The bin sizes for each dimension. */ template -std::array calc_bin_sizes(std::array, Dims> const &limits, - std::array const &n_bins) { +std::array +calc_bin_sizes(std::array, Dims> const &limits, + std::array const &n_bins) { std::array tmp; for (size_t ind = 0; ind < Dims; ++ind) { tmp[ind] = (limits[ind].second - limits[ind].first) / n_bins[ind]; @@ -147,8 +147,9 @@ template class Histogram { * histogram. */ template -Histogram::Histogram(std::array n_bins, size_t n_dims_data, - std::array, Dims> limits) +Histogram::Histogram(std::array n_bins, + size_t n_dims_data, + std::array, Dims> limits) : m_n_bins(n_bins), m_limits(limits), m_n_dims_data(n_dims_data) { if (n_bins.size() != limits.size()) { throw std::invalid_argument("Argument for number of bins and limits do " @@ -168,7 +169,8 @@ Histogram::Histogram(std::array n_bins, size_t n_dims_dat * The size of the given vector has to match the number * of dimensions of the histogram. */ -template void Histogram::update(std::vector const &data) { +template +void Histogram::update(std::vector const &data) { if (check_limits(data, m_limits)) { std::vector weights(m_n_dims_data, static_cast(1.0)); update(data, weights); @@ -184,14 +186,15 @@ template void Histogram::update(std::vector void Histogram::update(std::vector const &data, - std::vector const &weights) { + std::vector const &weights) { if (check_limits(data, m_limits)) { std::vector index; for (size_t dim = 0; dim < m_n_bins.size(); ++dim) { index.push_back(calculate_bin_index(data[dim], m_bin_sizes[dim], m_limits[dim].first)); } - size_t flat_index = m_n_dims_data * ::Utils::ravel_index(index, m_n_bins); + size_t flat_index = + m_n_dims_data * ::Utils::ravel_index(index, m_n_bins); if (weights.size() != m_n_dims_data) throw std::invalid_argument("Wrong dimensions of given weights!"); for (size_t ind = 0; ind < m_n_dims_data; ++ind) { @@ -204,14 +207,16 @@ void Histogram::update(std::vector const &data, /** * \brief Get the bin sizes. */ -template std::array Histogram::get_bin_sizes() const { +template +std::array Histogram::get_bin_sizes() const { return m_bin_sizes; } /** * \brief Get the number of bins for each dimension. */ -template std::array Histogram::get_n_bins() const { +template +std::array Histogram::get_n_bins() const { return m_n_bins; } @@ -226,21 +231,25 @@ std::array, Dims> Histogram::get_limits() const { /** * \brief Get the histogram data. */ -template std::vector Histogram::get_histogram() const { +template +std::vector Histogram::get_histogram() const { return m_hist; } /** * \brief Get the histogram count data. */ -template std::vector Histogram::get_tot_count() const { +template +std::vector Histogram::get_tot_count() const { return m_tot_count; } /** * \brief Histogram normalization. (private member function can be overridden by * subclasses). */ -template void Histogram::normalize() { do_normalize(); } +template void Histogram::normalize() { + do_normalize(); +} /** * \brief Histogram normalization. @@ -253,7 +262,8 @@ template void Histogram::do_normalize() { [bin_volume](T v) { return v / bin_volume; }); } -template class CylindricalHistogram : public Histogram { +template +class CylindricalHistogram : public Histogram { public: using Histogram::Histogram; using Histogram::get_n_bins; diff --git a/src/core/utils/List.hpp b/src/core/utils/List.hpp index a0c2f2472c..4ce395f949 100644 --- a/src/core/utils/List.hpp +++ b/src/core/utils/List.hpp @@ -14,7 +14,8 @@ namespace Utils { /** List. Use the functions specified in list operations. */ template class List { - static_assert(std::is_unsigned::value, "SizeType needs to be unsigned."); + static_assert(std::is_unsigned::value, + "SizeType needs to be unsigned."); public: using value_type = T; diff --git a/src/core/utils/NoOp.hpp b/src/core/utils/NoOp.hpp index f908e6c8cd..3d2510235a 100644 --- a/src/core/utils/NoOp.hpp +++ b/src/core/utils/NoOp.hpp @@ -10,6 +10,5 @@ class NoOp { public: template void operator()(Args...) const { return; } }; - } #endif diff --git a/src/core/utils/Span.hpp b/src/core/utils/Span.hpp index 1f64a22a52..4aed7f5bd2 100644 --- a/src/core/utils/Span.hpp +++ b/src/core/utils/Span.hpp @@ -8,14 +8,14 @@ #include namespace Utils { - namespace detail { - template - using decay_t = typename std::decay::type; +namespace detail { +template using decay_t = typename std::decay::type; - template - using has_data = std::is_convertible< - decay_t().data())> *, T * const*>; - } +template +using has_data = + std::is_convertible().data())> *, + T *const *>; +} /** * @brief A sripped-down version of std::span from C++17. @@ -41,26 +41,31 @@ template class Span { T *m_ptr; size_t m_size{}; - template - using enable_if_const_t = typename std::enable_if::value, U>::type; + template + using enable_if_const_t = + typename std::enable_if::value, U>::type; template - using enable_if_mutable_t = typename std::enable_if::value, U>::type; + using enable_if_mutable_t = + typename std::enable_if::value, U>::type; template - using enable_if_has_data_t = typename std::enable_if::value, U>::type; + using enable_if_has_data_t = + typename std::enable_if::value, U>::type; public: Span() = default; Span(const Span &) = default; Span &operator=(const Span &) = default; - constexpr Span(pointer array, size_type length) : m_ptr(array), m_size(length) {} - template - constexpr Span(T (&a)[N]) noexcept : Span(a, N) {} + constexpr Span(pointer array, size_type length) + : m_ptr(array), m_size(length) {} + template constexpr Span(T (&a)[N]) noexcept : Span(a, N) {} - template, typename = enable_if_has_data_t> - explicit Span(C & c) noexcept : Span(c.data(), c.size()) {} - template, typename = enable_if_has_data_t> - Span(const C & c) noexcept : Span(c.data(), c.size()) {} + template , + typename = enable_if_has_data_t> + explicit Span(C &c) noexcept : Span(c.data(), c.size()) {} + template , + typename = enable_if_has_data_t> + Span(const C &c) noexcept : Span(c.data(), c.size()) {} constexpr size_type size() const { return m_size; } constexpr bool empty() const { return size() == 0; } @@ -77,9 +82,9 @@ template class Span { } constexpr reference at(size_type i) const { - return (i < size()) - ? m_ptr[i] - : throw std::out_of_range("span access out of bounds."), m_ptr[i]; + return (i < size()) ? m_ptr[i] + : throw std::out_of_range("span access out of bounds."), + m_ptr[i]; } constexpr pointer data() const { return m_ptr; } diff --git a/src/core/utils/checks/charge_neutrality.hpp b/src/core/utils/checks/charge_neutrality.hpp index 940f728066..2836bbd94d 100644 --- a/src/core/utils/checks/charge_neutrality.hpp +++ b/src/core/utils/checks/charge_neutrality.hpp @@ -10,9 +10,8 @@ namespace Utils { template -bool check_charge_neutrality( - ParticleRange &prange, - double relative_tolerance = 1e-12) { +bool check_charge_neutrality(ParticleRange &prange, + double relative_tolerance = 1e-12) { using namespace boost::accumulators; using KahanSum = accumulator_set>; diff --git a/src/core/utils/keys.hpp b/src/core/utils/keys.hpp index 7ab98e1ab8..da1a4d0458 100644 --- a/src/core/utils/keys.hpp +++ b/src/core/utils/keys.hpp @@ -20,28 +20,28 @@ #ifndef UTILS_KEYS_HPP #define UTILS_KEYS_HPP -#include #include +#include namespace Utils { - /** - * @brief Return the keys of a map type. - * - * Returns a vector of copies of the keys - * of a map, unordered_map, ... - */ - template - auto keys(Map const &m) -> std::vector { - using value_type = typename Map::value_type; - using std::begin; - using std::end; - - std::vector ret(m.size()); - - std::transform(begin(m), end(m), ret.begin(), - [](value_type const &kv) { return kv.first; }); - return ret; - } +/** + * @brief Return the keys of a map type. + * + * Returns a vector of copies of the keys + * of a map, unordered_map, ... + */ +template +auto keys(Map const &m) -> std::vector { + using value_type = typename Map::value_type; + using std::begin; + using std::end; + + std::vector ret(m.size()); + + std::transform(begin(m), end(m), ret.begin(), + [](value_type const &kv) { return kv.first; }); + return ret; +} } #endif diff --git a/src/core/utils/make_unique.hpp b/src/core/utils/make_unique.hpp index 8524e39b00..c9b97adb1b 100644 --- a/src/core/utils/make_unique.hpp +++ b/src/core/utils/make_unique.hpp @@ -30,8 +30,7 @@ namespace Utils { * This function is part of the standard from c++14 on. */ template -std::unique_ptr make_unique(Args &&... args) -{ +std::unique_ptr make_unique(Args &&... args) { return std::unique_ptr(new T(std::forward(args)...)); } diff --git a/src/core/utils/math/sqr.hpp b/src/core/utils/math/sqr.hpp index fc3ef1b16e..6d462b7d30 100644 --- a/src/core/utils/math/sqr.hpp +++ b/src/core/utils/math/sqr.hpp @@ -2,9 +2,8 @@ #define UTILS_MATH_SQR_HPP namespace Utils { - /** Calculates the SQuaRe of 'double' x, returning 'double'. */ - template inline T sqr(T x) { return x * x; } - +/** Calculates the SQuaRe of 'double' x, returning 'double'. */ +template inline T sqr(T x) { return x * x; } } #endif diff --git a/src/core/utils/memory.hpp b/src/core/utils/memory.hpp index 86c4b55d39..3bf1ce149b 100644 --- a/src/core/utils/memory.hpp +++ b/src/core/utils/memory.hpp @@ -7,17 +7,17 @@ namespace Utils { - /*************************************************************/ - /** \name Dynamic memory allocation. */ - /*************************************************************/ - /*@{*/ - - /* to enable us to make sure that freed pointers are invalidated, we normally - try to use realloc. - Unfortunately allocating zero bytes (which should be avoided) actually - allocates 16 bytes, and - reallocating to 0 also. To avoid this, we use our own malloc and realloc - procedures. */ +/*************************************************************/ +/** \name Dynamic memory allocation. */ +/*************************************************************/ +/*@{*/ + +/* to enable us to make sure that freed pointers are invalidated, we normally + try to use realloc. + Unfortunately allocating zero bytes (which should be avoided) actually + allocates 16 bytes, and + reallocating to 0 also. To avoid this, we use our own malloc and realloc + procedures. */ /** used instead of realloc. Makes sure that resizing to zero FREEs pointer */ diff --git a/src/core/utils/mpi/detail/size_and_offset.hpp b/src/core/utils/mpi/detail/size_and_offset.hpp index 94005a6a6b..a796d1d03a 100644 --- a/src/core/utils/mpi/detail/size_and_offset.hpp +++ b/src/core/utils/mpi/detail/size_and_offset.hpp @@ -22,8 +22,8 @@ #define UTILS_MPI_DETAIL_SIZE_AND_OFFSET_HPP #include -#include #include +#include #include #include @@ -34,7 +34,8 @@ namespace detail { template int size_and_offset(std::vector &sizes, std::vector &displ, - int n_elem, const boost::mpi::communicator &comm, int root = 0) { + int n_elem, const boost::mpi::communicator &comm, + int root = 0) { sizes.resize(comm.size()); displ.resize(comm.size()); @@ -52,7 +53,8 @@ int size_and_offset(std::vector &sizes, std::vector &displ, return total_size; } -inline void size_and_offset(int n_elem, const boost::mpi::communicator &comm, int root = 0) { +inline void size_and_offset(int n_elem, const boost::mpi::communicator &comm, + int root = 0) { /* Send local size */ boost::mpi::gather(comm, n_elem, root); } diff --git a/src/core/utils/mpi/gather_buffer.hpp b/src/core/utils/mpi/gather_buffer.hpp index 8bf31bc3d9..4248e3a948 100644 --- a/src/core/utils/mpi/gather_buffer.hpp +++ b/src/core/utils/mpi/gather_buffer.hpp @@ -70,8 +70,8 @@ int gather_buffer(T *buffer, int n_elem, boost::mpi::communicator comm, } else { detail::size_and_offset(n_elem, comm, root); /* Send data */ - gatherv(comm, buffer, n_elem, static_cast(nullptr), - nullptr, nullptr, root); + gatherv(comm, buffer, n_elem, static_cast(nullptr), nullptr, nullptr, + root); return 0; } @@ -101,7 +101,7 @@ void gather_buffer(std::vector &buffer, boost::mpi::communicator comm, static std::vector displ; auto const tot_size = - detail::size_and_offset(sizes, displ, n_elem, comm, root); + detail::size_and_offset(sizes, displ, n_elem, comm, root); /* Resize the buffer */ buffer.resize(tot_size); diff --git a/src/core/utils/mpi/gatherv.hpp b/src/core/utils/mpi/gatherv.hpp index 949897243e..a8c39b1c78 100644 --- a/src/core/utils/mpi/gatherv.hpp +++ b/src/core/utils/mpi/gatherv.hpp @@ -85,13 +85,13 @@ void gatherv(const boost::mpi::communicator &comm, const T *in_values, } } - template - void gatherv(const boost::mpi::communicator &comm, const T *in_values, - int in_size, int root) { - assert(comm.rank() != root && "This overload can not be called on the root rank."); - gatherv(comm, in_values, in_size, static_cast(nullptr), 0, 0, root); - } - +template +void gatherv(const boost::mpi::communicator &comm, const T *in_values, + int in_size, int root) { + assert(comm.rank() != root && + "This overload can not be called on the root rank."); + gatherv(comm, in_values, in_size, static_cast(nullptr), 0, 0, root); +} } } #endif diff --git a/src/core/utils/mpi/scatter_buffer.hpp b/src/core/utils/mpi/scatter_buffer.hpp index f8839c28dd..bf8d22ce5d 100644 --- a/src/core/utils/mpi/scatter_buffer.hpp +++ b/src/core/utils/mpi/scatter_buffer.hpp @@ -26,8 +26,8 @@ #include #include -#include #include +#include namespace Utils { namespace Mpi { @@ -50,7 +50,7 @@ void scatter_buffer(T *buffer, int n_elem, boost::mpi::communicator comm, detail::size_and_offset(sizes, displ, n_elem, comm, root); - for(int i = 0; i < comm.size(); i++) { + for (int i = 0; i < comm.size(); i++) { sizes[i] *= sizeof(T); displ[i] *= sizeof(T); } diff --git a/src/core/utils/parallel/Callback.hpp b/src/core/utils/parallel/Callback.hpp index 3d08d340ee..2e8658fa09 100644 --- a/src/core/utils/parallel/Callback.hpp +++ b/src/core/utils/parallel/Callback.hpp @@ -35,7 +35,8 @@ namespace Parallel { class Callback { public: Callback(Communication::MpiCallbacks &cb, - const Communication::MpiCallbacks::function_type &callback) : m_cb(cb) { + const Communication::MpiCallbacks::function_type &callback) + : m_cb(cb) { m_callback_id = m_cb.add(callback); } @@ -46,13 +47,11 @@ class Callback { * * The callback is not run on the calling node. */ - void call(int a = 0, int b = 0) { - m_cb.call(m_callback_id, a, b); - } + void call(int a = 0, int b = 0) { m_cb.call(m_callback_id, a, b); } private: /* Callback system we're on */ - Communication::MpiCallbacks & m_cb; + Communication::MpiCallbacks &m_cb; /* Id of the encapsulated callback */ int m_callback_id; }; diff --git a/src/core/utils/parallel/ParallelObject.hpp b/src/core/utils/parallel/ParallelObject.hpp index 4d89dbc326..2d6642425f 100644 --- a/src/core/utils/parallel/ParallelObject.hpp +++ b/src/core/utils/parallel/ParallelObject.hpp @@ -30,13 +30,11 @@ class ParallelObject { public: ParallelObject() = delete; - static void register_callback(Communication::MpiCallbacks & cb) { + static void register_callback(Communication::MpiCallbacks &cb) { cb.add(&mpi_callback); } - static void make(Communication::MpiCallbacks & cb) { - cb.call(&mpi_callback); - } + static void make(Communication::MpiCallbacks &cb) { cb.call(&mpi_callback); } private: /* Supported callback types. Currently we can only create new instances. */ diff --git a/src/core/utils/serialization/CUDA_particle_data.hpp b/src/core/utils/serialization/CUDA_particle_data.hpp index ef1fc6472f..7fc3605841 100644 --- a/src/core/utils/serialization/CUDA_particle_data.hpp +++ b/src/core/utils/serialization/CUDA_particle_data.hpp @@ -9,7 +9,7 @@ BOOST_IS_BITWISE_SERIALIZABLE(CUDA_particle_data) - namespace boost { +namespace boost { namespace serialization { template void load(Archive &ar, CUDA_particle_data &p, diff --git a/src/core/utils/serialization/List.hpp b/src/core/utils/serialization/List.hpp index d1ca54b320..68431a574a 100644 --- a/src/core/utils/serialization/List.hpp +++ b/src/core/utils/serialization/List.hpp @@ -1,8 +1,8 @@ #ifndef CORE_UTILS_SERIALIZATION_LIST_HPP #define CORE_UTILS_SERIALIZATION_LIST_HPP +#include #include -#include #include "core/utils/List.hpp" diff --git a/src/core/utils/serialization/ParticleList.hpp b/src/core/utils/serialization/ParticleList.hpp index 0ccf061875..a47d2ceceb 100644 --- a/src/core/utils/serialization/ParticleList.hpp +++ b/src/core/utils/serialization/ParticleList.hpp @@ -6,8 +6,7 @@ namespace boost { namespace serialization { template -void load(Archive &ar, ParticleList &pl, - const unsigned int /* version */) { +void load(Archive &ar, ParticleList &pl, const unsigned int /* version */) { int size; ar >> size; diff --git a/src/core/utils/statistics/RunningAverage.hpp b/src/core/utils/statistics/RunningAverage.hpp index 408ebe74a8..893d645fa2 100644 --- a/src/core/utils/statistics/RunningAverage.hpp +++ b/src/core/utils/statistics/RunningAverage.hpp @@ -22,9 +22,9 @@ #ifndef __RUNING_AVERAGE_HPP #define __RUNING_AVERAGE_HPP +#include #include #include -#include namespace Utils { namespace Statistics { @@ -36,10 +36,9 @@ namespace Statistics { template class RunningAverage { public: RunningAverage() - : m_n(0), m_old_avg(0), m_new_avg(0), m_old_var(0), - m_new_var(0.0), m_min(std::numeric_limits::max()), - m_max(-std::numeric_limits::max()) - {} + : m_n(0), m_old_avg(0), m_new_avg(0), m_old_var(0), m_new_var(0.0), + m_min(std::numeric_limits::max()), + m_max(-std::numeric_limits::max()) {} void add_sample(Scalar s) { m_n++; diff --git a/src/core/virtual_sites.cpp b/src/core/virtual_sites.cpp index b5e95691f5..3df162fa06 100755 --- a/src/core/virtual_sites.cpp +++ b/src/core/virtual_sites.cpp @@ -19,13 +19,13 @@ along with this program. If not, see . */ -#include "config.hpp" #include "virtual_sites.hpp" -#include "initialize.hpp" -#include "statistics.hpp" -#include "integrate.hpp" -#include "rotation.hpp" #include "communication.hpp" +#include "config.hpp" +#include "initialize.hpp" +#include "integrate.hpp" +#include "rotation.hpp" +#include "statistics.hpp" #ifdef VIRTUAL_SITES @@ -33,151 +33,152 @@ namespace { std::shared_ptr m_virtual_sites; } -const std::shared_ptr& virtual_sites() { - return m_virtual_sites; -} +const std::shared_ptr &virtual_sites() { return m_virtual_sites; } -void set_virtual_sites(std::shared_ptr const& v) { - m_virtual_sites=v; - recalc_forces=1; - invalidate_obs(); - on_ghost_flags_change(); +void set_virtual_sites(std::shared_ptr const &v) { + m_virtual_sites = v; + recalc_forces = 1; + invalidate_obs(); + on_ghost_flags_change(); } #ifdef VIRTUAL_SITES_RELATIVE - -void calculate_vs_relate_to_params(const Particle& p_current, const Particle& p_relate_to, double& l, Vector<4,double>& quat) -{ - // get the distance between the particles - Vector3d d; - get_mi_vector(d, p_current.r.p,p_relate_to.r.p); - - // Check, if the distance between virtual and non-virtual particles is larger htan minimum global cutoff - // If so, warn user - l=sqrt(sqrlen(d)); - if (l>min_global_cut && n_nodes>1) { - runtimeErrorMsg() << "Warning: The distance between virtual and non-virtual particle (" << l << ") is\nlarger than the minimum global cutoff (" << min_global_cut << "). This may lead to incorrect simulations\nunder certain conditions. Set the \"System()\" class property \"min_global_cut\" to\nincrease the minimum cutoff.\n"; - } - - // Now, calculate the quaternions which specify the angle between - // the director of the particel we relate to and the vector - // (paritlce_we_relate_to - this_particle) - // The vs_relative implemnation later obtains the direcotr by multiplying - // the quaternions representing the orientation of the real particle - // with those in the virtual particle. The re quulting quaternion is then - // converted to a director. - // Whe have quat_(real particle) *quat_(virtual particle) - // = quat_(obtained from desired director) - // Resolving this for the quat_(virtaul particle) - - //Normalize desired director - int i; - - // If the distance between real & virtual particle is 0 - // we just set the relative orientation to 1 0 0 0, as it is irrelevant but - // needs to be a valid quaternion - if (l!=0) - { - for (i=0;i<3;i++) - d[i]/=l; - - // Obtain quaternions from desired director - Vector<4,double> quat_director; - convert_quatu_to_quat(d, quat_director); - - // Define quat as described above: - double x=0; - for (i=0;i<4;i++) - x+=p_relate_to.r.quat[i]*p_relate_to.r.quat[i]; - - quat[0]=0; - for (i=0;i<4;i++) - quat[0] +=p_relate_to.r.quat[i]*quat_director[i]; - - quat[1] =-quat_director[0] *p_relate_to.r.quat[1] - +quat_director[1] *p_relate_to.r.quat[0] - +quat_director[2] *p_relate_to.r.quat[3] - -quat_director[3] *p_relate_to.r.quat[2]; - quat[2] =p_relate_to.r.quat[1] *quat_director[3] - + p_relate_to.r.quat[0] *quat_director[2] - - p_relate_to.r.quat[3] *quat_director[1] - - p_relate_to.r.quat[2] * quat_director[0]; - quat[3] =quat_director[3] *p_relate_to.r.quat[0] - - p_relate_to.r.quat[3] *quat_director[0] - + p_relate_to.r.quat[2] * quat_director[1] - - p_relate_to.r.quat[1] *quat_director[2]; - for (i=0;i<4;i++) - quat[i]/=x; - - - // Verify result - double qtemp[4]; - multiply_quaternions(p_relate_to.r.quat,quat,qtemp); - for (i=0;i<4;i++) - if (fabs(qtemp[i]-quat_director[i])>1E-9) - fprintf(stderr, "vs_relate_to: component %d: %f instead of %f\n", - i, qtemp[i], quat_director[i]); - } - else - { - quat[0]=1; - quat[1]=quat[2]=quat[3]=0; - } -} +void calculate_vs_relate_to_params(const Particle &p_current, + const Particle &p_relate_to, double &l, + Vector<4, double> &quat) { + // get the distance between the particles + Vector3d d; + get_mi_vector(d, p_current.r.p, p_relate_to.r.p); + + // Check, if the distance between virtual and non-virtual particles is larger + // htan minimum global cutoff + // If so, warn user + l = sqrt(sqrlen(d)); + if (l > min_global_cut && n_nodes > 1) { + runtimeErrorMsg() + << "Warning: The distance between virtual and non-virtual particle (" + << l << ") is\nlarger than the minimum global cutoff (" + << min_global_cut + << "). This may lead to incorrect simulations\nunder certain " + "conditions. Set the \"System()\" class property \"min_global_cut\" " + "to\nincrease the minimum cutoff.\n"; + } + + // Now, calculate the quaternions which specify the angle between + // the director of the particel we relate to and the vector + // (paritlce_we_relate_to - this_particle) + // The vs_relative implemnation later obtains the direcotr by multiplying + // the quaternions representing the orientation of the real particle + // with those in the virtual particle. The re quulting quaternion is then + // converted to a director. + // Whe have quat_(real particle) *quat_(virtual particle) + // = quat_(obtained from desired director) + // Resolving this for the quat_(virtaul particle) + + // Normalize desired director + int i; + + // If the distance between real & virtual particle is 0 + // we just set the relative orientation to 1 0 0 0, as it is irrelevant but + // needs to be a valid quaternion + if (l != 0) { + for (i = 0; i < 3; i++) + d[i] /= l; + + // Obtain quaternions from desired director + Vector<4, double> quat_director; + convert_quatu_to_quat(d, quat_director); + + // Define quat as described above: + double x = 0; + for (i = 0; i < 4; i++) + x += p_relate_to.r.quat[i] * p_relate_to.r.quat[i]; + + quat[0] = 0; + for (i = 0; i < 4; i++) + quat[0] += p_relate_to.r.quat[i] * quat_director[i]; + + quat[1] = -quat_director[0] * p_relate_to.r.quat[1] + + quat_director[1] * p_relate_to.r.quat[0] + + quat_director[2] * p_relate_to.r.quat[3] - + quat_director[3] * p_relate_to.r.quat[2]; + quat[2] = p_relate_to.r.quat[1] * quat_director[3] + + p_relate_to.r.quat[0] * quat_director[2] - + p_relate_to.r.quat[3] * quat_director[1] - + p_relate_to.r.quat[2] * quat_director[0]; + quat[3] = quat_director[3] * p_relate_to.r.quat[0] - + p_relate_to.r.quat[3] * quat_director[0] + + p_relate_to.r.quat[2] * quat_director[1] - + p_relate_to.r.quat[1] * quat_director[2]; + for (i = 0; i < 4; i++) + quat[i] /= x; + + // Verify result + double qtemp[4]; + multiply_quaternions(p_relate_to.r.quat, quat, qtemp); + for (i = 0; i < 4; i++) + if (fabs(qtemp[i] - quat_director[i]) > 1E-9) + fprintf(stderr, "vs_relate_to: component %d: %f instead of %f\n", i, + qtemp[i], quat_director[i]); + } else { + quat[0] = 1; + quat[1] = quat[2] = quat[3] = 0; + } +} -// Setup the virtual_sites_relative properties of a particle so that the given virtaul particle will follow the given real particle -int vs_relate_to(int part_num, int relate_to) -{ - // Get the data for the particle we act on and the one we wnat to relate - // it to. - auto const &p_current = get_particle_data(part_num); - auto const &p_relate_to = get_particle_data(relate_to); - - Vector<4,double> quat; - double l; - calculate_vs_relate_to_params(p_current, p_relate_to, l, quat); - - // Set the particle id of the particle we want to relate to, the distance - // and the relative orientation - if (set_particle_vs_relative(part_num, relate_to, l, quat.data()) == ES_ERROR) { - runtimeErrorMsg() << "setting the vs_relative attributes failed"; - return ES_ERROR; - } - set_particle_virtual(part_num,1); - - return ES_OK; +// Setup the virtual_sites_relative properties of a particle so that the given +// virtaul particle will follow the given real particle +int vs_relate_to(int part_num, int relate_to) { + // Get the data for the particle we act on and the one we wnat to relate + // it to. + auto const &p_current = get_particle_data(part_num); + auto const &p_relate_to = get_particle_data(relate_to); + + Vector<4, double> quat; + double l; + calculate_vs_relate_to_params(p_current, p_relate_to, l, quat); + + // Set the particle id of the particle we want to relate to, the distance + // and the relative orientation + if (set_particle_vs_relative(part_num, relate_to, l, quat.data()) == + ES_ERROR) { + runtimeErrorMsg() << "setting the vs_relative attributes failed"; + return ES_ERROR; + } + set_particle_virtual(part_num, 1); + + return ES_OK; } -// Setup the virtual_sites_relative properties of a particle so that the given virtual particle will follow the given real particle -// Local version, expects both particles to be accessible through local_particles +// Setup the virtual_sites_relative properties of a particle so that the given +// virtual particle will follow the given real particle +// Local version, expects both particles to be accessible through +// local_particles // and only executes the changes on the virtual site locally -int local_vs_relate_to(int part_num, int relate_to) -{ - // Get the data for the particle we act on and the one we want to relate - // it to. - Particle* p_current=local_particles[part_num]; - Particle* p_relate_to=local_particles[relate_to]; - if ((p_current == NULL) || (p_relate_to==NULL)) { - runtimeErrorMsg() << "Could not retrieve particle data for the given ids from local_particles[p[]"; - return ES_ERROR; - } - - Vector<4,double> quat; - double l; - calculate_vs_relate_to_params(*p_current, *p_relate_to, l, quat); - - - // Set the particle id of the particle we want to relate to, the distnace - // and the relative orientation - p_current->p.vs_relative_to_particle_id = relate_to; - p_current->p.vs_relative_distance = l; - for (int i = 0; i < 4; i++) - p_current->p.vs_relative_rel_orientation[i] = quat[i]; - return ES_OK; +int local_vs_relate_to(int part_num, int relate_to) { + // Get the data for the particle we act on and the one we want to relate + // it to. + Particle *p_current = local_particles[part_num]; + Particle *p_relate_to = local_particles[relate_to]; + if ((p_current == NULL) || (p_relate_to == NULL)) { + runtimeErrorMsg() << "Could not retrieve particle data for the given ids " + "from local_particles[p[]"; + return ES_ERROR; + } + + Vector<4, double> quat; + double l; + calculate_vs_relate_to_params(*p_current, *p_relate_to, l, quat); + + // Set the particle id of the particle we want to relate to, the distnace + // and the relative orientation + p_current->p.vs_relative_to_particle_id = relate_to; + p_current->p.vs_relative_distance = l; + for (int i = 0; i < 4; i++) + p_current->p.vs_relative_rel_orientation[i] = quat[i]; + return ES_OK; } - - #endif #endif diff --git a/src/core/virtual_sites.hpp b/src/core/virtual_sites.hpp index d9fa4ae6d5..b580759628 100644 --- a/src/core/virtual_sites.hpp +++ b/src/core/virtual_sites.hpp @@ -4,23 +4,24 @@ #include "config.hpp" #ifdef VIRTUAL_SITES -#include "virtual_sites/VirtualSites.hpp" +#include "virtual_sites/VirtualSites.hpp" /** @brief get active virtual sites implementation */ -const std::shared_ptr& virtual_sites(); +const std::shared_ptr &virtual_sites(); /** @brief Set active virtual sites implementation */ -void set_virtual_sites(std::shared_ptr const& v); +void set_virtual_sites(std::shared_ptr const &v); #ifdef VIRTUAL_SITES_RELATIVE int vs_relate_to(int part_num, int relate_to); -// Setup the virtual_sites_relative properties of a particle so that the given virtaul particle will follow the given real particle -// Local version, expects both particles to be accessible through local_particles +// Setup the virtual_sites_relative properties of a particle so that the given +// virtaul particle will follow the given real particle +// Local version, expects both particles to be accessible through +// local_particles // and only executes the changes on the virtual site locally int local_vs_relate_to(int part_num, int relate_to); - #endif #endif #endif diff --git a/src/core/virtual_sites/VirtualSites.hpp b/src/core/virtual_sites/VirtualSites.hpp index 6f72128157..ca184a8c00 100755 --- a/src/core/virtual_sites/VirtualSites.hpp +++ b/src/core/virtual_sites/VirtualSites.hpp @@ -21,7 +21,6 @@ #ifndef VIRTUAL_SITES_VIRTUAL_SITES_HPP #define VIRTUAL_SITES_VIRTUAL_SITES_HPP - /** \file virtual_sites.hpp * This file contains routine to handle virtual sites * Virtual sites are like particles, but they will be not integrated. @@ -38,41 +37,45 @@ /** @brief Base class for virtual sites implementations */ class VirtualSites { - public: - VirtualSites() : m_have_velocity(true), m_have_quaternion(false) {}; - /** @brief Update positions and/or velocities of virtual sites +public: + VirtualSites() : m_have_velocity(true), m_have_quaternion(false){}; + /** @brief Update positions and/or velocities of virtual sites - * Velocities are only updated if have_velocity() returns true. - * @param recalc_positions can be used to skip the reculation of positions. - */ - virtual void update(bool recalc_positions=true) const =0; - /** Back-transfer forces (and torques) to non-virtual particles. */ - virtual void back_transfer_forces_and_torques() const =0; - /** @brief Called after force calculation (and before rattle/shake) */ - virtual void after_force_calc() {}; - virtual void after_lb_propagation() {}; - /** @brief Number of pressure contributions */ - virtual int n_pressure_contribs() const {return 0;}; - /** @brief Pressure contribution(). */ - virtual void pressure_and_stress_tensor_contribution(double* pressure, double* stress_tensor) const {}; - /** @brief Enable/disable velocity calculations for vs. */ - void set_have_velocity(const bool& v) { m_have_velocity=v; }; - const bool& get_have_velocity() const { return m_have_velocity; }; - /** @brief Enable/disable quaternion calculations for vs.*/ - void set_have_quaternion(const bool& have_quaternion) { m_have_quaternion=have_quaternion; }; - bool get_have_quaternion() const { return m_have_quaternion; }; - /** @brief Is a ghost communication needed after position updates */ - virtual bool need_ghost_comm_after_pos_update() const =0; - /** Is a ghost comm needed before a velocity update */ - virtual bool need_ghost_comm_before_vel_update() const =0; - /** Is a ghost comm needed before the back_transfer */ - virtual bool need_ghost_comm_before_back_transfer() const =0; - virtual ~VirtualSites() {} - private: - bool m_have_velocity; - bool m_have_quaternion; - }; + * Velocities are only updated if have_velocity() returns true. + * @param recalc_positions can be used to skip the reculation of positions. + */ + virtual void update(bool recalc_positions = true) const = 0; + /** Back-transfer forces (and torques) to non-virtual particles. */ + virtual void back_transfer_forces_and_torques() const = 0; + /** @brief Called after force calculation (and before rattle/shake) */ + virtual void after_force_calc(){}; + virtual void after_lb_propagation(){}; + /** @brief Number of pressure contributions */ + virtual int n_pressure_contribs() const { return 0; }; + /** @brief Pressure contribution(). */ + virtual void + pressure_and_stress_tensor_contribution(double *pressure, + double *stress_tensor) const {}; + /** @brief Enable/disable velocity calculations for vs. */ + void set_have_velocity(const bool &v) { m_have_velocity = v; }; + const bool &get_have_velocity() const { return m_have_velocity; }; + /** @brief Enable/disable quaternion calculations for vs.*/ + void set_have_quaternion(const bool &have_quaternion) { + m_have_quaternion = have_quaternion; + }; + bool get_have_quaternion() const { return m_have_quaternion; }; + /** @brief Is a ghost communication needed after position updates */ + virtual bool need_ghost_comm_after_pos_update() const = 0; + /** Is a ghost comm needed before a velocity update */ + virtual bool need_ghost_comm_before_vel_update() const = 0; + /** Is a ghost comm needed before the back_transfer */ + virtual bool need_ghost_comm_before_back_transfer() const = 0; + virtual ~VirtualSites() {} +private: + bool m_have_velocity; + bool m_have_quaternion; +}; #endif #endif diff --git a/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp b/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp index a30d91451c..7719fa19d3 100644 --- a/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp +++ b/src/core/virtual_sites/VirtualSitesInertialessTracers.cpp @@ -1,36 +1,33 @@ -#include "config.hpp" +#include "config.hpp" #ifdef VIRTUAL_SITES_INERTIALESS_TRACERS +#include "VirtualSitesInertialessTracers.hpp" +#include "cells.hpp" +#include "errorhandling.hpp" +#include "lattice.hpp" #include "virtual_sites/lb_inertialess_tracers.hpp" -#include "errorhandling.hpp" -#include "VirtualSitesInertialessTracers.hpp" -#include "lattice.hpp" -#include "cells.hpp" - void VirtualSitesInertialessTracers::after_force_calc() { - // Now the forces are computed and need to go into the LB fluid +// Now the forces are computed and need to go into the LB fluid #ifdef LB - if (lattice_switch & LATTICE_LB) { - IBM_ForcesIntoFluid_CPU(); - return; - } + if (lattice_switch & LATTICE_LB) { + IBM_ForcesIntoFluid_CPU(); + return; + } #endif #ifdef LB_GPU - if (lattice_switch & LATTICE_LB_GPU) { - IBM_ForcesIntoFluid_GPU(local_cells.particles()); - return; - } + if (lattice_switch & LATTICE_LB_GPU) { + IBM_ForcesIntoFluid_GPU(local_cells.particles()); + return; + } #endif -runtimeErrorMsg() << "Inertialess Tracers: No LB method was active."; + runtimeErrorMsg() << "Inertialess Tracers: No LB method was active."; } - - void VirtualSitesInertialessTracers::after_lb_propagation() { #ifdef VIRTUAL_SITES_INERTIALESS_TRACERS - IBM_UpdateParticlePositions(local_cells.particles()); + IBM_UpdateParticlePositions(local_cells.particles()); // We reset all since otherwise the halo nodes may not be reset // NB: the normal Espresso reset is also done after applying the forces // if (lattice_switch & LATTICE_LB) IBM_ResetLBForces_CPU(); @@ -38,12 +35,11 @@ void VirtualSitesInertialessTracers::after_lb_propagation() { // if (lattice_switch & LATTICE_LB_GPU) IBM_ResetLBForces_GPU(); #endif - - // Ghost positions are now out-of-date - // We should update. - // Actually we seem to get the same results whether we do this here or not, - // but it is safer to do it - ghost_communicator(&cell_structure.update_ghost_pos_comm); + // Ghost positions are now out-of-date + // We should update. + // Actually we seem to get the same results whether we do this here or not, + // but it is safer to do it + ghost_communicator(&cell_structure.update_ghost_pos_comm); #endif // VS inertialess tracers } diff --git a/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp b/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp index 7b64c405b4..e3bae356f6 100644 --- a/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp +++ b/src/core/virtual_sites/VirtualSitesInertialessTracers.hpp @@ -1,32 +1,31 @@ #ifndef VIRTUAL_SITES_VIRTUAL_SITES_INERTIALESS_TRACERS_HPP #define VIRTUAL_SITES_VIRTUAL_SITES_INERTIALESS_TRACERS_HPP - -#include "config.hpp" +#include "config.hpp" #ifdef VIRTUAL_SITES -#include "VirtualSites.hpp" - +#include "VirtualSites.hpp" #ifdef VIRTUAL_SITES_INERTIALESS_TRACERS -/** @brief Virtual sites which are advected with an lb fuid. Forces on them are instantaneously transferred to the fluid */ - class VirtualSitesInertialessTracers : public VirtualSites { - /** @brief Update positions and/or velocities of virtual sites +/** @brief Virtual sites which are advected with an lb fuid. Forces on them are + * instantaneously transferred to the fluid */ +class VirtualSitesInertialessTracers : public VirtualSites { + /** @brief Update positions and/or velocities of virtual sites - * Velocities are only updated update_velocities() return true - * @param recalc_positions can be used to skip the reculation of positions - */ - void update(bool recalc_positions=true) const override {}; - /** Back-transfer forces (and torques) to non-virtual particles */ - void back_transfer_forces_and_torques() const override {}; - void after_force_calc() override; - void after_lb_propagation() override; - /** @brief Is a ghost communication needed after position updates */ - bool need_ghost_comm_after_pos_update() const override { return false;} - /** Is a ghost comm needed before a velocity update */ - bool need_ghost_comm_before_vel_update() const override {return false;}; - /** Is a ghost comm needed before back_transfer */ - bool need_ghost_comm_before_back_transfer() const override {return false;}; - }; + * Velocities are only updated update_velocities() return true + * @param recalc_positions can be used to skip the reculation of positions + */ + void update(bool recalc_positions = true) const override{}; + /** Back-transfer forces (and torques) to non-virtual particles */ + void back_transfer_forces_and_torques() const override{}; + void after_force_calc() override; + void after_lb_propagation() override; + /** @brief Is a ghost communication needed after position updates */ + bool need_ghost_comm_after_pos_update() const override { return false; } + /** Is a ghost comm needed before a velocity update */ + bool need_ghost_comm_before_vel_update() const override { return false; }; + /** Is a ghost comm needed before back_transfer */ + bool need_ghost_comm_before_back_transfer() const override { return false; }; +}; #endif #endif diff --git a/src/core/virtual_sites/VirtualSitesOff.hpp b/src/core/virtual_sites/VirtualSitesOff.hpp index 18aec598b4..8c8c411eb1 100644 --- a/src/core/virtual_sites/VirtualSitesOff.hpp +++ b/src/core/virtual_sites/VirtualSitesOff.hpp @@ -1,30 +1,27 @@ #ifndef VIRTUAL_SITES_VIRTUAL_SITES_OFF_HPP #define VIRTUAL_SITES_VIRTUAL_SITES_OFF_HPP - -#include "config.hpp" +#include "config.hpp" #ifdef VIRTUAL_SITES -#include "VirtualSites.hpp" - +#include "VirtualSites.hpp" /** @brief Do-nothing virtual-sites implementation */ - class VirtualSitesOff : public VirtualSites { - /** @brief Update positions and/or velocities of virtual sites +class VirtualSitesOff : public VirtualSites { + /** @brief Update positions and/or velocities of virtual sites - * Velocities are only updated update_velocities() return true - * @param recalc_positions can be used to skip the reculation of positions - */ - void update(bool recalc_positions=true) const override {}; - /** Back-transfer forces (and torques) to non-virtual particles */ - void back_transfer_forces_and_torques() const override {}; - /** @brief Is a ghost communication needed after position updates */ - bool need_ghost_comm_after_pos_update() const override { return false;} - /** Is a ghost comm needed before a velocity update */ - bool need_ghost_comm_before_vel_update() const override {return false;}; - /** Is a ghost comm needed before back_transfer */ - bool need_ghost_comm_before_back_transfer() const override {return false;}; - }; + * Velocities are only updated update_velocities() return true + * @param recalc_positions can be used to skip the reculation of positions + */ + void update(bool recalc_positions = true) const override{}; + /** Back-transfer forces (and torques) to non-virtual particles */ + void back_transfer_forces_and_torques() const override{}; + /** @brief Is a ghost communication needed after position updates */ + bool need_ghost_comm_after_pos_update() const override { return false; } + /** Is a ghost comm needed before a velocity update */ + bool need_ghost_comm_before_vel_update() const override { return false; }; + /** Is a ghost comm needed before back_transfer */ + bool need_ghost_comm_before_back_transfer() const override { return false; }; +}; #endif #endif - diff --git a/src/core/virtual_sites/VirtualSitesRelative.cpp b/src/core/virtual_sites/VirtualSitesRelative.cpp index 1240c478cf..a423ffa81c 100755 --- a/src/core/virtual_sites/VirtualSitesRelative.cpp +++ b/src/core/virtual_sites/VirtualSitesRelative.cpp @@ -1,162 +1,159 @@ /* Copyright (C) 2010,2011,2012,2013,2014,2015,2016 The ESPResSo project - + This file is part of ESPResSo. - + ESPResSo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + ESPResSo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ -#include "config.hpp" #include "VirtualSitesRelative.hpp" -#include "rotation.hpp" -#include "errorhandling.hpp" -#include "grid.hpp" #include "cells.hpp" +#include "config.hpp" +#include "errorhandling.hpp" +#include "grid.hpp" +#include "rotation.hpp" #ifdef VIRTUAL_SITES_RELATIVE void VirtualSitesRelative::update(bool recalc_positions) const { -for (auto& p : local_cells.particles()) { - if (!p.p.is_virtual) continue; - - if (recalc_positions) - update_pos(p); - - if (get_have_velocity()) - update_vel(p); + for (auto &p : local_cells.particles()) { + if (!p.p.is_virtual) + continue; - if (get_have_quaternion()) - update_virtual_particle_quaternion(p); + if (recalc_positions) + update_pos(p); -} + if (get_have_velocity()) + update_vel(p); + if (get_have_quaternion()) + update_virtual_particle_quaternion(p); + } } - - -void VirtualSitesRelative::update_virtual_particle_quaternion(Particle& p) const { - const Particle *p_real = local_particles[p.p.vs_relative_to_particle_id]; - if (!p_real) - { - throw std::runtime_error("virtual_sites_relative.cpp - update_mol_pos_particle(): No real particle associated with virtual site.\n"); - } - multiply_quaternions(p_real->r.quat, p.p.vs_quat, p.r.quat); - convert_quat_to_quatu(p.r.quat, p.r.quatu); +void VirtualSitesRelative::update_virtual_particle_quaternion( + Particle &p) const { + const Particle *p_real = local_particles[p.p.vs_relative_to_particle_id]; + if (!p_real) { + throw std::runtime_error("virtual_sites_relative.cpp - " + "update_mol_pos_particle(): No real particle " + "associated with virtual site.\n"); + } + multiply_quaternions(p_real->r.quat, p.p.vs_quat, p.r.quat); + convert_quat_to_quatu(p.r.quat, p.r.quatu); #ifdef DIPOLES // When dipoles are enabled, update dipole moment convert_quatu_to_dip(p.r.quatu, p.p.dipm, p.r.dip); #endif } - - // This is the "relative" implementation for virtual sites. // Virtual particles are placed relative to the position of a real particle // Obtain the real particle from which a virtual particle derives it's position // Note: for now, we use the mol_di property of Particle -// Update the pos of the given virtual particle as defined by the real +// Update the pos of the given virtual particle as defined by the real // particles in the same molecule -void VirtualSitesRelative::update_pos(Particle& p) const -{ - // First obtain the real particle responsible for this virtual particle: - // Find the 1st real particle in the topology for the virtual particle's mol_id - const Particle *p_real = local_particles[p.p.vs_relative_to_particle_id]; - // Check, if a real particle was found - if (!p_real) - { - runtimeErrorMsg() <<"virtual_sites_relative.cpp - update_mol_pos_particle(): No real particle associated with virtual site.\n"; - return; - } - - // Calculate the quaternion defining the orientation of the vecotr connectinhg - // the virtual site and the real particle - // This is obtained, by multiplying the quaternion representing the director - // of the real particle with the quaternion of the virtual particle, which - // specifies the relative orientation. - Vector<4,double> q; - multiply_quaternions(p_real->r.quat,p.p.vs_relative_rel_orientation,q); - // Calculate the director resulting from the quaternions - Vector3d director={0,0,0}; - convert_quat_to_quatu(q,director); - // normalize - double l =sqrt(sqrlen(director)); - // Division comes in the loop below - - // Calculate the new position of the virtual sites from - // position of real particle + director - int i; - double new_pos[3]; - double tmp; - for (i=0;i<3;i++) - { - new_pos[i] =p_real->r.p[i] +director[i]/l*p.p.vs_relative_distance; - double old=p.r.p[i]; - // Handle the case that one of the particles had gone over the periodic - // boundary and its coordinate has been folded - if (PERIODIC(i)) - { - tmp =p.r.p[i] -new_pos[i]; - if (tmp > box_l[i]/2.) { - p.r.p[i] =new_pos[i] + box_l[i]; - } - else if (tmp < -box_l[i]/2.) { - p.r.p[i] =new_pos[i] - box_l[i]; +void VirtualSitesRelative::update_pos(Particle &p) const { + // First obtain the real particle responsible for this virtual particle: + // Find the 1st real particle in the topology for the virtual particle's + // mol_id + const Particle *p_real = local_particles[p.p.vs_relative_to_particle_id]; + // Check, if a real particle was found + if (!p_real) { + runtimeErrorMsg() << "virtual_sites_relative.cpp - " + "update_mol_pos_particle(): No real particle " + "associated with virtual site.\n"; + return; + } + + // Calculate the quaternion defining the orientation of the vecotr connectinhg + // the virtual site and the real particle + // This is obtained, by multiplying the quaternion representing the director + // of the real particle with the quaternion of the virtual particle, which + // specifies the relative orientation. + Vector<4, double> q; + multiply_quaternions(p_real->r.quat, p.p.vs_relative_rel_orientation, q); + // Calculate the director resulting from the quaternions + Vector3d director = {0, 0, 0}; + convert_quat_to_quatu(q, director); + // normalize + double l = sqrt(sqrlen(director)); + // Division comes in the loop below + + // Calculate the new position of the virtual sites from + // position of real particle + director + int i; + double new_pos[3]; + double tmp; + for (i = 0; i < 3; i++) { + new_pos[i] = p_real->r.p[i] + director[i] / l * p.p.vs_relative_distance; + double old = p.r.p[i]; + // Handle the case that one of the particles had gone over the periodic + // boundary and its coordinate has been folded + if (PERIODIC(i)) { + tmp = p.r.p[i] - new_pos[i]; + if (tmp > box_l[i] / 2.) { + p.r.p[i] = new_pos[i] + box_l[i]; + } else if (tmp < -box_l[i] / 2.) { + p.r.p[i] = new_pos[i] - box_l[i]; + } else + p.r.p[i] = new_pos[i]; + } else + p.r.p[i] = new_pos[i]; + // Has the vs moved by more than a skin + if (fabs(old - p.r.p[i]) > skin) { + runtimeErrorMsg() << "Virtual site " << p.p.identity + << " has moved by more than the skin." << old << "->" + << p.r.p[i]; } - else p.r.p[i] =new_pos[i]; - } - else p.r.p[i] =new_pos[i]; - // Has the vs moved by more than a skin - if (fabs(old- p.r.p[i]) >skin) { - runtimeErrorMsg() << "Virtual site "<" <r.p); - - // Get omega of real particle in space-fixed frame - double omega_space_frame[3]; - convert_omega_body_to_space(p_real,omega_space_frame); - // Obtain velocity from v=v_real particle + omega_real_particle \times director - vector_product(omega_space_frame,d,p.m.v); - - int i; - // Add prefactors and add velocity of real particle - for (i=0;i<3;i++) - { - // Scale the velocity by the distance of virtual particle from the real particle - // Add velocity of real particle - p.m.v[i] += p_real->m.v[i]; - } +void VirtualSitesRelative::update_vel(Particle &p) const { + // First obtain the real particle responsible for this virtual particle: + Particle *p_real = local_particles[p.p.vs_relative_to_particle_id]; + // Check, if a real particle was found + if (!p_real) { + runtimeErrorMsg() << "virtual_sites_relative.cpp - " + "update_mol_pos_particle(): No real particle " + "associated with virtual site.\n"; + return; + } + + double d[3]; + get_mi_vector(d, p.r.p, p_real->r.p); + + // Get omega of real particle in space-fixed frame + double omega_space_frame[3]; + convert_omega_body_to_space(p_real, omega_space_frame); + // Obtain velocity from v=v_real particle + omega_real_particle \times + // director + vector_product(omega_space_frame, d, p.m.v); + + int i; + // Add prefactors and add velocity of real particle + for (i = 0; i < 3; i++) { + // Scale the velocity by the distance of virtual particle from the real + // particle + // Add velocity of real particle + p.m.v[i] += p_real->m.v[i]; + } } // Distribute forces that have accumulated on virtual particles to the @@ -186,21 +183,21 @@ void VirtualSitesRelative::back_transfer_forces_and_torques() const { // Add forces and torques for (int j = 0; j < 3; j++) { - p_real->f.torque[j] += tmp[j]+p.f.torque[j]; + p_real->f.torque[j] += tmp[j] + p.f.torque[j]; p_real->f.f[j] += p.f.f[j]; } } } } - -// Setup the virtual_sites_relative properties of a particle so that the given virtaul particle will follow the given real particle - - +// Setup the virtual_sites_relative properties of a particle so that the given +// virtaul particle will follow the given real particle // Rigid body conribution to scalar pressure and stress tensor -void VirtualSitesRelative::pressure_and_stress_tensor_contribution(double* pressure, double* stress_tensor) const { - // Division by 3 volume is somewhere else. (pressure.cpp after all presure calculations) +void VirtualSitesRelative::pressure_and_stress_tensor_contribution( + double *pressure, double *stress_tensor) const { + // Division by 3 volume is somewhere else. (pressure.cpp after all presure + // calculations) // Iterate over all the particles in the local cells for (auto &p : local_cells.particles()) { @@ -227,8 +224,6 @@ void VirtualSitesRelative::pressure_and_stress_tensor_contribution(double* press // but the 1/3 is applied somewhere else. *pressure += (p.f.f[0] * d[0] + p.f.f[1] * d[1] + p.f.f[2] * d[2]); } - } #endif - diff --git a/src/core/virtual_sites/lb_inertialess_tracers.cpp b/src/core/virtual_sites/lb_inertialess_tracers.cpp index 332b4191a8..bba2dd2841 100644 --- a/src/core/virtual_sites/lb_inertialess_tracers.cpp +++ b/src/core/virtual_sites/lb_inertialess_tracers.cpp @@ -6,6 +6,7 @@ #ifdef VIRTUAL_SITES_INERTIALESS_TRACERS #include "cells.hpp" +#include "grid.hpp" #include "halo.hpp" #include "integrate.hpp" #include "lb.hpp" @@ -13,7 +14,6 @@ #include "particle_data.hpp" #include "virtual_sites/lb_inertialess_tracers.hpp" #include "virtual_sites/lb_inertialess_tracers_cuda_interface.hpp" -#include "grid.hpp" // ****** Functions for internal use ******** @@ -91,14 +91,15 @@ Usually the reset would be done by Espresso after the LB update. But we need to keep the forces till after the position update for the f/2 term ****************/ -void IBM_ResetLBForces_CPU() -{ - for (int i = 0; ip.is_virtual) { - calc_mol_vel(p,v_com); - for (j=0;j<3;j++){ - p->m.v[j] = v_com[j]; - } - } +void update_mol_vel_particle(Particle *p) { + int j; + double v_com[3]; + if (p->p.is_virtual) { + calc_mol_vel(p, v_com); + for (j = 0; j < 3; j++) { + p->m.v[j] = v_com[j]; + } + } } - -void update_mol_pos_particle(Particle *p){ - int j; - double r_com[3]; - if (p->p.is_virtual) { - calc_mol_pos(p,r_com); - for (j=0;j<3;j++){ - p->r.p[j] = r_com[j]; - } - } +void update_mol_pos_particle(Particle *p) { + int j; + double r_com[3]; + if (p->p.is_virtual) { + calc_mol_pos(p, r_com); + for (j = 0; j < 3; j++) { + p->r.p[j] = r_com[j]; + } + } } void distribute_mol_force() { @@ -67,171 +66,189 @@ void distribute_mol_force() { } } -void calc_mol_vel(Particle *p_com,double v_com[3]){ - int i,j,mol_id; - double M=0; - Particle *p; +void calc_mol_vel(Particle *p_com, double v_com[3]) { + int i, j, mol_id; + double M = 0; + Particle *p; #ifdef VIRTUAL_SITES_DEBUG - int count=0; + int count = 0; #endif - for (i=0;i<3;i++){ - v_com[i]=0.0; - } - mol_id=p_com->p.mol_id; - for (i=0;ip.is_virtual) continue; - for (j=0;j<3;j++){ - v_com[j] += (*p).p.mass*p->m.v[j]; - } - M+=(*p).p.mass; + for (i = 0; i < 3; i++) { + v_com[i] = 0.0; + } + mol_id = p_com->p.mol_id; + for (i = 0; i < topology[mol_id].part.n; i++) { + p = local_particles[topology[mol_id].part.e[i]]; #ifdef VIRTUAL_SITES_DEBUG - count++; + if (p == nullptr) { + runtimeErrorMsg() << "Particle does not exist in calc_mol_vel! id= " + << topology[mol_id].part.e[i] << "\n"; + return; + } #endif - } - for (j=0;j<3;j++){ - v_com[j] /= M; - } + if (p->p.is_virtual) + continue; + for (j = 0; j < 3; j++) { + v_com[j] += (*p).p.mass * p->m.v[j]; + } + M += (*p).p.mass; #ifdef VIRTUAL_SITES_DEBUG - if (count!=topology[mol_id].part.n-1){ - runtimeErrorMsg() <<"There is more than one COM in calc_mol_vel! mol_id= " << mol_id << "\n"; - return; - } + count++; +#endif + } + for (j = 0; j < 3; j++) { + v_com[j] /= M; + } +#ifdef VIRTUAL_SITES_DEBUG + if (count != topology[mol_id].part.n - 1) { + runtimeErrorMsg() << "There is more than one COM in calc_mol_vel! mol_id= " + << mol_id << "\n"; + return; + } #endif } -/* this is a local version of center of mass, because ghosts don't have image boxes*/ +/* this is a local version of center of mass, because ghosts don't have image + * boxes*/ /* but p_com is a real particle */ -void calc_mol_pos(Particle *p_com,double r_com[3]){ - int i,j,mol_id; - double M=0; - double vec12[3]; - Particle *p; +void calc_mol_pos(Particle *p_com, double r_com[3]) { + int i, j, mol_id; + double M = 0; + double vec12[3]; + Particle *p; #ifdef VIRTUAL_SITES_DEBUG - int count=0; + int count = 0; #endif - for (i=0;i<3;i++){ - r_com[i]=0.0; - } - mol_id=p_com->p.mol_id; - for (i=0;ip.is_virtual) continue; - get_mi_vector(vec12,p->r.p, p_com->r.p); - for (j=0;j<3;j++){ - r_com[j] += (*p).p.mass*vec12[j]; - } - M+=(*p).p.mass; + for (i = 0; i < 3; i++) { + r_com[i] = 0.0; + } + mol_id = p_com->p.mol_id; + for (i = 0; i < topology[mol_id].part.n; i++) { + p = local_particles[topology[mol_id].part.e[i]]; #ifdef VIRTUAL_SITES_DEBUG - count++; + if (p == nullptr) { + runtimeErrorMsg() << "Particle does not exist in calc_mol_pos! id= " + << topology[mol_id].part.e[i] << "\n"; + return; + } #endif - } - for (j=0;j<3;j++){ - r_com[j] /= M; - r_com[j] += p_com->r.p[j]; - } + if (p->p.is_virtual) + continue; + get_mi_vector(vec12, p->r.p, p_com->r.p); + for (j = 0; j < 3; j++) { + r_com[j] += (*p).p.mass * vec12[j]; + } + M += (*p).p.mass; #ifdef VIRTUAL_SITES_DEBUG - if (count!=topology[mol_id].part.n-1){ - runtimeErrorMsg() <<"There is more than one COM in calc_mol_pos! mol_id= " << mol_id << "\n"; - return; - } + count++; +#endif + } + for (j = 0; j < 3; j++) { + r_com[j] /= M; + r_com[j] += p_com->r.p[j]; + } +#ifdef VIRTUAL_SITES_DEBUG + if (count != topology[mol_id].part.n - 1) { + runtimeErrorMsg() << "There is more than one COM in calc_mol_pos! mol_id= " + << mol_id << "\n"; + return; + } #endif } -void put_mol_force_on_parts(Particle *p_com){ - int i,j,mol_id; - Particle *p; - double force[3],M; +void put_mol_force_on_parts(Particle *p_com) { + int i, j, mol_id; + Particle *p; + double force[3], M; #ifdef VIRTUAL_SITES_DEBUG - int count=0; + int count = 0; #endif - mol_id=p_com->p.mol_id; - for (i=0;i<3;i++){ - force[i]=p_com->f.f[i]; - p_com->f.f[i]=0.0; - } + mol_id = p_com->p.mol_id; + for (i = 0; i < 3; i++) { + force[i] = p_com->f.f[i]; + p_com->f.f[i] = 0.0; + } #ifdef MASS - M=0; - for (i=0;ip.is_virtual) continue; - M+=(*p).p.mass; - } + M = 0; + for (i = 0; i < topology[mol_id].part.n; i++) { + p = local_particles[topology[mol_id].part.e[i]]; +#ifdef VIRTUAL_SITES_DEBUG + if (p == nullptr) { + runtimeErrorMsg() + << "Particle does not exist in put_mol_force_on_parts! id= " + << topology[mol_id].part.e[i] << "\n"; + return; + } +#endif + if (p->p.is_virtual) + continue; + M += (*p).p.mass; + } #else - M=topology[mol_id].part.n-1; + M = topology[mol_id].part.n - 1; #endif - for (i=0;ip.is_virtual) { - for (j=0;j<3;j++){ - p->f.f[j]+=(*p).p.mass*force[j]/M; - } + for (i = 0; i < topology[mol_id].part.n; i++) { + p = local_particles[topology[mol_id].part.e[i]]; #ifdef VIRTUAL_SITES_DEBUG - count++; + if (p == nullptr) { + runtimeErrorMsg() + << "Particle does not exist in put_mol_force_on_parts! id= " + << topology[mol_id].part.e[i] << "\n"; + return; + } #endif + if (!p->p.is_virtual) { + for (j = 0; j < 3; j++) { + p->f.f[j] += (*p).p.mass * force[j] / M; } - } #ifdef VIRTUAL_SITES_DEBUG - if (count!=topology[mol_id].part.n-1){ - runtimeErrorMsg() <<"There is more than one COM input_mol_force_on_parts! mol_id= " << mol_id << "\n"; - return; - } + count++; +#endif + } + } +#ifdef VIRTUAL_SITES_DEBUG + if (count != topology[mol_id].part.n - 1) { + runtimeErrorMsg() + << "There is more than one COM input_mol_force_on_parts! mol_id= " + << mol_id << "\n"; + return; + } #endif } -Particle *get_mol_com_particle(Particle *calling_p){ - int mol_id; - int i; - Particle *p; +Particle *get_mol_com_particle(Particle *calling_p) { + int mol_id; + int i; + Particle *p; - mol_id=calling_p->p.mol_id; + mol_id = calling_p->p.mol_id; - if (mol_id < 0) { - runtimeErrorMsg() <<"Particle does not have a mol id! pnr= " << calling_p->p.identity << "\n"; - return nullptr; - } - for (i=0;ip.is_virtual) { - return p; - } - } + if (p->p.is_virtual) { + return p; + } + } - runtimeErrorMsg() <<"No com found in get_mol_com_particleParticle does not exist in put_mol_force_on_parts! pnr= " << calling_p->p.identity << "\n"; - return nullptr; + runtimeErrorMsg() << "No com found in get_mol_com_particleParticle does not " + "exist in put_mol_force_on_parts! pnr= " + << calling_p->p.identity << "\n"; + return nullptr; - return calling_p; + return calling_p; } - #endif