![]() |
ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
|
00001 /* 00002 Copyright (C) 2010,2012,2013 The ESPResSo project 00003 Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 00004 Max-Planck-Institute for Polymer Research, Theory Group 00005 00006 This file is part of ESPResSo. 00007 00008 ESPResSo is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation, either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 ESPResSo is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 /** \file energy.c 00022 Implementation of \ref energy.h "energy.h". 00023 */ 00024 #include "energy.h" 00025 #include "cells.h" 00026 #include "integrate.h" 00027 #include "initialize.h" 00028 #include "domain_decomposition.h" 00029 #include "nsquare.h" 00030 #include "layered.h" 00031 #include "elc.h" 00032 #include "magnetic_non_p3m_methods.h" 00033 #include "mdlc_correction.h" 00034 00035 Observable_stat energy = {0, {NULL,0,0}, 0,0,0}; 00036 Observable_stat total_energy = {0, {NULL,0,0}, 0,0,0}; 00037 00038 /************************************************************/ 00039 /* local prototypes */ 00040 /************************************************************/ 00041 00042 /** Calculate long range energies (P3M, MMM2d...). */ 00043 void calc_long_range_energies(); 00044 00045 /************************************************************/ 00046 00047 void energy_calc(double *result) 00048 { 00049 if (!check_obs_calc_initialized()) 00050 return; 00051 00052 init_energies(&energy); 00053 00054 on_observable_calc(); 00055 00056 switch (cell_structure.type) { 00057 case CELL_STRUCTURE_LAYERED: 00058 layered_calculate_energies(); 00059 break; 00060 case CELL_STRUCTURE_DOMDEC: 00061 if(dd.use_vList) { 00062 if (rebuild_verletlist) 00063 build_verlet_lists(); 00064 calculate_verlet_energies(); 00065 } 00066 else 00067 calculate_link_cell_energies(); 00068 break; 00069 case CELL_STRUCTURE_NSQUARE: 00070 nsq_calculate_energies(); 00071 } 00072 /* rescale kinetic energy */ 00073 energy.data.e[0] /= (2.0*time_step*time_step); 00074 00075 calc_long_range_energies(); 00076 00077 /* gather data */ 00078 MPI_Reduce(energy.data.e, result, energy.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); 00079 } 00080 00081 /************************************************************/ 00082 00083 void calc_long_range_energies() 00084 { 00085 #ifdef ELECTROSTATICS 00086 /* calculate k-space part of electrostatic interaction. */ 00087 switch (coulomb.method) { 00088 #ifdef P3M 00089 case COULOMB_P3M: 00090 p3m_charge_assign(); 00091 energy.coulomb[1] = p3m_calc_kspace_forces(0,1); 00092 break; 00093 case COULOMB_ELC_P3M: 00094 // assign the original charges first 00095 // they may not have been assigned yet 00096 p3m_charge_assign(); 00097 if(!elc_params.dielectric_contrast_on) 00098 energy.coulomb[1] = p3m_calc_kspace_forces(0,1); 00099 else { 00100 energy.coulomb[1] = 0.5*p3m_calc_kspace_forces(0,1); 00101 energy.coulomb[1]+= 0.5*ELC_P3M_dielectric_layers_energy_self(); 00102 00103 // assign both original and image charges now 00104 ELC_p3m_charge_assign_both(); 00105 ELC_P3M_modify_p3m_sums_both(); 00106 00107 energy.coulomb[1] += 0.5*p3m_calc_kspace_forces(0,1); 00108 00109 //assign only the image charges now 00110 ELC_p3m_charge_assign_image(); 00111 ELC_P3M_modify_p3m_sums_image(); 00112 00113 energy.coulomb[1]-= 0.5*p3m_calc_kspace_forces(0,1); 00114 } 00115 energy.coulomb[2] = ELC_energy(); 00116 break; 00117 #endif 00118 case COULOMB_MMM2D: 00119 *energy.coulomb += MMM2D_far_energy(); 00120 *energy.coulomb += MMM2D_dielectric_layers_energy_contribution(); 00121 break; 00122 /* calculate electric part of energy (only for MAGGS) */ 00123 case COULOMB_MAGGS: 00124 *energy.coulomb += maggs_electric_energy(); 00125 break; 00126 } 00127 #endif /* ifdef ELECTROSTATICS */ 00128 00129 #ifdef DIPOLES 00130 switch (coulomb.Dmethod) { 00131 #ifdef DP3M 00132 case DIPOLAR_P3M: 00133 dp3m_dipole_assign(); 00134 energy.dipolar[1] = dp3m_calc_kspace_forces(0,1); 00135 break; 00136 case DIPOLAR_MDLC_P3M: 00137 dp3m_dipole_assign(); 00138 energy.dipolar[1] = dp3m_calc_kspace_forces(0,1); 00139 energy.dipolar[2] = add_mdlc_energy_corrections(); 00140 break; 00141 #endif 00142 case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: 00143 energy.dipolar[1] = dawaanr_calculations(0,1); 00144 break; 00145 case DIPOLAR_MDLC_DS: 00146 energy.dipolar[1] = magnetic_dipolar_direct_sum_calculations(0,1); 00147 energy.dipolar[2] = add_mdlc_energy_corrections(); 00148 break; 00149 case DIPOLAR_DS: 00150 energy.dipolar[1] = magnetic_dipolar_direct_sum_calculations(0,1); 00151 break; 00152 00153 } 00154 #endif /* ifdef DIPOLES */ 00155 00156 } 00157 00158 /************************************************************/ 00159 00160 void init_energies(Observable_stat *stat) 00161 { 00162 int n_pre, n_non_bonded, n_coulomb, n_dipolar; 00163 00164 n_pre = 1; 00165 n_non_bonded = (n_particle_types*(n_particle_types+1))/2; 00166 00167 n_coulomb = 0; 00168 #ifdef ELECTROSTATICS 00169 switch (coulomb.method) { 00170 case COULOMB_NONE: n_coulomb = 0; break; 00171 #ifdef P3M 00172 case COULOMB_ELC_P3M: n_coulomb = 3; break; 00173 case COULOMB_P3M: n_coulomb = 2; break; 00174 #endif 00175 default: n_coulomb = 1; 00176 } 00177 #endif 00178 00179 n_dipolar = 0; 00180 #ifdef DIPOLES 00181 00182 switch (coulomb.Dmethod) { 00183 case DIPOLAR_NONE: n_dipolar = 1; break; 00184 #ifdef DP3M 00185 case DIPOLAR_MDLC_P3M: n_dipolar=3; break; 00186 case DIPOLAR_P3M: n_dipolar = 2; break; 00187 #endif 00188 case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: n_dipolar = 2; break; 00189 case DIPOLAR_MDLC_DS: n_dipolar=3; break; 00190 case DIPOLAR_DS: n_dipolar = 2; break; 00191 } 00192 00193 #endif 00194 00195 obsstat_realloc_and_clear(stat, n_pre, n_bonded_ia, n_non_bonded, n_coulomb, n_dipolar, 1); 00196 stat->init_status = 0; 00197 } 00198 00199 /************************************************************/ 00200 00201 void master_energy_calc() { 00202 mpi_gather_stats(1, total_energy.data.e, NULL, NULL, NULL); 00203 00204 total_energy.init_status=1; 00205 }
1.7.5.1