/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2012 University of Bonn. All rights reserved. * Copyright (C) 2013 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder 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. * * MoleCuilder 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 MoleCuilder. If not, see . */ /* * MPQCCommandJob_MPQCData.cpp * * Created on: Feb 08, 2012 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "MPQCData.hpp" #include #include #include "CodePatterns/Log.hpp" #include "LinearAlgebra/defs.hpp" MPQCData::MPQCData(const SamplingGridProperties &_props) : DoLongrange(DontSampleDensity), DoValenceOnly(DoSampleValenceOnly), sampled_grid(_props), accuracy(0.), desired_accuracy(0.) {} MPQCData::MPQCData() : DoLongrange(DontSampleDensity), DoValenceOnly(DoSampleValenceOnly), accuracy(0.), desired_accuracy(0.) {} MPQCData::energy_t::energy_t() : total(0.), nuclear_repulsion(0.), electron_coulomb(0.), electron_exchange(0.), correlation(0.), overlap(0.), kinetic(0.), hcore(0.) {} MPQCData::times_t::times_t() : total_walltime(0.), total_cputime(0.), total_flops(0.), gather_walltime(0.), gather_cputime(0.), gather_flops(0.) {} /** Comparator for class MPQCData. * */ bool MPQCData::operator==(const MPQCData &other) const { if (fabs(energies.total - other.energies.total) > std::numeric_limits::epsilon()) { LOG(1, "INFO: Energy's in MPQCData differ: " << energies.total << " != " << other.energies.total << "."); return false; } if (forces.size() != other.forces.size()) { LOG(1, "INFO: Forces's in MPQCData differ in size: " << forces.size() << " != " << other.forces.size() << "."); return false; } for (size_t i = 0; i < forces.size(); ++i) for (size_t index = 0; index < NDIM; ++index) if (fabs(forces[i][index] - other.forces[i][index]) > std::numeric_limits::epsilon()) { LOG(1, "INFO: " << index << "th component of force of particle " << i << " in MPQCData differ: " << forces[i][index] << " != " << other.forces[i][index] << "."); return false; } return true; } void MPQCData::assignWithDownsampledGrid( MPQCData &instance, const MPQCData &other) { if (&instance != &other) { instance.energies = other.energies; instance.forces = other.forces; instance.DoLongrange = other.DoLongrange; instance.DoValenceOnly = other.DoValenceOnly; /** We need to return from the local grid of the fragment to the global * grid and change the level in such a way that the gridpoints remain exactly * the same. */ SamplingGridProperties domain(instance.sampled_grid); //!> we need to downsample by the difference in levels and by the smaller grid size const double surplus_level = instance.sampled_grid.getSurplusLevel(other.sampled_grid); ASSERT( fabs(surplus_level - round(surplus_level)) < std::numeric_limits::epsilon()*1e4, "MPQCData::assignWithDownsampledGrid() - surplus level is not integer: " +toString(surplus_level)); const int downsample_level = (other.sampled_grid.level - instance.sampled_grid.level) + round(surplus_level); // downsample the stored grid values to the coarser grid SamplingGrid::downsample( instance.sampled_grid, other.sampled_grid, other.sampled_grid.level - downsample_level); // then we can simply take over #ifndef NDEBUG const size_t window_gridpoints = instance.sampled_grid.getWindowGridPoints(); #endif static_cast(instance.sampled_grid) = domain; ASSERT(instance.sampled_grid.getWindowGridPoints() == window_gridpoints, "MPQCData::assignWithDownsampledGrid() - number of window gridpoints is " +toString(instance.sampled_grid.getWindowGridPoints())+" and was "+toString(window_gridpoints)); instance.positions = other.positions; instance.charges = other.charges; instance.times = other.times; instance.accuracy = other.accuracy; instance.desired_accuracy = other.desired_accuracy; } } std::ostream & operator<<(std::ostream &ost, const MPQCData &data) { ost << "Energy: " << data.energies.total << "\t"; ost << "Forces: " << data.forces << "\t"; ost << "Times: " << data.times.total_walltime << ", " << data.times.total_cputime << ", " << data.times.total_flops << ", "; ost << "Accuracy: " << data.accuracy << "\t"; ost << "Desired accuracy: " << data.desired_accuracy << "\t"; return ost; }