![]() |
ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
|
00001 /* 00002 Copyright (C) 2010,2011,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 statistics_fluid.c 00022 * 00023 * Fluid related analysis functions. 00024 * Implementation of \ref statistics_fluid.h. 00025 * 00026 */ 00027 00028 #include <mpi.h> 00029 #include "utils.h" 00030 #include "communication.h" 00031 #include "lb.h" 00032 #include "lb-boundaries.h" 00033 #include "statistics_fluid.h" 00034 00035 #ifdef LB 00036 00037 //#include <fftw3.h> 00038 00039 /** Caclulate mass of the LB fluid. 00040 * \param result Fluid mass 00041 */ 00042 void lb_calc_fluid_mass(double *result) { 00043 int x, y, z, index; 00044 double sum_rho=0.0, rho=0.0; 00045 00046 for (x=1; x<=lblattice.grid[0]; x++) { 00047 for (y=1; y<=lblattice.grid[1]; y++) { 00048 for (z=1; z<=lblattice.grid[2]; z++) { 00049 index = get_linear_index(x,y,z,lblattice.halo_grid); 00050 00051 lb_calc_local_rho(index,&rho); 00052 //fprintf(stderr,"(%d,%d,%d) %e\n",x,y,z,rho); 00053 sum_rho += rho; 00054 00055 } 00056 } 00057 } 00058 00059 MPI_Reduce(&sum_rho, result, 1, MPI_DOUBLE, MPI_SUM, 0, comm_cart); 00060 } 00061 00062 /** Calculate momentum of the LB fluid. 00063 * \param result Fluid momentum 00064 */ 00065 void lb_calc_fluid_momentum(double *result) { 00066 00067 int x, y, z, index; 00068 double j[3], momentum[3] = { 0.0, 0.0, 0.0 }; 00069 00070 for (x=1; x<=lblattice.grid[0]; x++) { 00071 for (y=1; y<=lblattice.grid[1]; y++) { 00072 for (z=1; z<=lblattice.grid[2]; z++) { 00073 index = get_linear_index(x,y,z,lblattice.halo_grid); 00074 00075 lb_calc_local_j(index,j); 00076 momentum[0] += j[0] + lbfields[index].force[0]; 00077 momentum[1] += j[1] + lbfields[index].force[1]; 00078 momentum[2] += j[2] + lbfields[index].force[2]; 00079 00080 } 00081 } 00082 } 00083 00084 momentum[0] *= lblattice.agrid/lbpar.tau; 00085 momentum[1] *= lblattice.agrid/lbpar.tau; 00086 momentum[2] *= lblattice.agrid/lbpar.tau; 00087 00088 MPI_Reduce(momentum, result, 3, MPI_DOUBLE, MPI_SUM, 0, comm_cart); 00089 00090 } 00091 00092 /** Calculate temperature of the LB fluid. 00093 * \param result Fluid temperature 00094 */ 00095 void lb_calc_fluid_temp(double *result) { 00096 int x, y, z, index; 00097 double rho, j[3]; 00098 double temp = 0.0; 00099 00100 for (x=1; x<=lblattice.grid[0]; x++) { 00101 for (y=1; y<=lblattice.grid[1]; y++) { 00102 for (z=1; z<=lblattice.grid[2]; z++) { 00103 index = get_linear_index(x,y,z,lblattice.halo_grid); 00104 00105 lb_calc_local_fields(index, &rho, j, NULL); 00106 00107 temp += scalar(j,j); 00108 } 00109 } 00110 } 00111 00112 temp *= 1./(3.*lbpar.rho*lblattice.grid_volume*lbpar.tau*lbpar.tau*lblattice.agrid)/n_nodes; 00113 00114 MPI_Reduce(&temp, result, 1, MPI_DOUBLE, MPI_SUM, 0, comm_cart); 00115 } 00116 00117 void lb_collect_boundary_forces(double *result) { 00118 #ifdef LB_BOUNDARIES 00119 double* boundary_forces=malloc(3*n_lb_boundaries*sizeof(double)); 00120 00121 for (int i = 0; i < n_lb_boundaries; i++) 00122 for (int j = 0; j < 3; j++) 00123 boundary_forces[3*i+j]=lb_boundaries[i].force[j]; 00124 00125 MPI_Reduce(boundary_forces, result, 3*n_lb_boundaries, MPI_DOUBLE, MPI_SUM, 0, comm_cart); 00126 free(boundary_forces); 00127 #endif 00128 } 00129 #define REQ_DENSPROF 702 00130 00131 /** Calculate a density profile of the fluid. */ 00132 void lb_calc_densprof(double *result, int *params) { 00133 00134 int index, dir[3], grid[3]; 00135 int newroot=0, subrank, involved=0; 00136 double *profile; 00137 MPI_Comm slice_comm; 00138 MPI_Status status; 00139 00140 if (this_node !=0) params = malloc(3*sizeof(int)); 00141 00142 MPI_Bcast(params, 3, MPI_INT, 0, comm_cart); 00143 00144 int pdir = params[0]; 00145 int x1 = params[1]; 00146 int x2 = params[2]; 00147 00148 dir[pdir] = 0; 00149 dir[(pdir+1)%3] = x1; 00150 dir[(pdir+2)%3] = x2; 00151 00152 newroot = map_lattice_to_node(&lblattice, dir, grid); 00153 map_node_array(this_node, node_pos); 00154 00155 if ( (grid[(pdir+1)%3] == node_pos[(pdir+1)%3]) 00156 && (grid[(pdir+2)%3] == node_pos[(pdir+2)%3]) ) { 00157 involved = 1; 00158 } 00159 00160 MPI_Comm_split(comm_cart, involved, this_node, &slice_comm); 00161 MPI_Comm_rank(slice_comm, &subrank); 00162 00163 if (this_node == newroot) 00164 result = realloc(result,box_l[pdir]/lblattice.agrid*sizeof(double)); 00165 00166 if (involved) { 00167 00168 profile = malloc(lblattice.grid[pdir]*sizeof(double)); 00169 00170 //dir[(pdir+1)%3] += 1; 00171 //dir[(pdir+2)%3] += 1; 00172 for (dir[pdir]=1;dir[pdir]<=lblattice.grid[pdir];dir[pdir]++) { 00173 00174 index = get_linear_index(dir[0],dir[1],dir[2],lblattice.halo_grid); 00175 lb_calc_local_rho(index,&profile[dir[pdir]-1]); 00176 //profile[dir[pdir]-1] = *lbfluid[index].rho; 00177 00178 //if (dir[pdir]==lblattice.grid[pdir]) { 00179 // int i; 00180 // fprintf(stderr,"(%d,%d,%d)\n",dir[0],dir[1],dir[2]); 00181 // fprintf(stderr,"%d\n",lbfluid[index].boundary); 00182 // for (i=0;i<lbmodel.n_veloc;i++) fprintf(stderr,"local_n[%p][%d]=%.12e\n",lbfluid[index].n,i,lbfluid[index].n[i]+lbmodel.coeff[i][0]*lbpar.rho); 00183 // fprintf(stderr,"local_rho=%e\n",*lbfluid[index].rho); 00184 //} 00185 00186 } 00187 00188 MPI_Gather(profile, lblattice.grid[pdir], MPI_DOUBLE, result, lblattice.grid[pdir], MPI_DOUBLE, 0, slice_comm); 00189 00190 free(profile); 00191 00192 } 00193 00194 MPI_Comm_free(&slice_comm); 00195 00196 if (newroot != 0) { 00197 if (this_node == newroot) { 00198 MPI_Send(result, lblattice.grid[pdir]*node_grid[pdir], MPI_DOUBLE, 0, REQ_DENSPROF, comm_cart); 00199 free(result); 00200 } 00201 if (this_node == 0) { 00202 MPI_Recv(result, lblattice.grid[pdir]*node_grid[pdir], MPI_DOUBLE, newroot, REQ_DENSPROF, comm_cart, &status); 00203 } 00204 } 00205 00206 if (this_node != 0) free(params); 00207 00208 } 00209 00210 #define REQ_VELPROF 701 00211 00212 /** Calculate a velocity profile for the LB fluid. */ 00213 void lb_calc_velprof(double *result, int *params) { 00214 00215 int index, dir[3], grid[3]; 00216 int newroot=0, subrank, involved=0; 00217 double rho, j[3], *velprof; 00218 MPI_Comm slice_comm; 00219 MPI_Status status; 00220 00221 if (this_node != 0) params = malloc(4*sizeof(int)); 00222 00223 MPI_Bcast(params, 4, MPI_INT, 0, comm_cart); 00224 00225 int vcomp = params[0]; 00226 int pdir = params[1]; 00227 int x1 = params[2]; 00228 int x2 = params[3]; 00229 00230 dir[pdir] = 0; 00231 dir[(pdir+1)%3] = x1; 00232 dir[(pdir+2)%3] = x2; 00233 00234 //fprintf(stderr,"%d: (%d,%d,%d)\n",this_node,dir[0],dir[1],dir[2]); 00235 00236 newroot = map_lattice_to_node(&lblattice, dir, grid); 00237 map_node_array(this_node, node_pos); 00238 00239 //fprintf(stderr,"%d: newroot=%d (%d,%d,%d)\n",this_node,newroot,grid[0],grid[1],grid[2]); 00240 00241 if ( (grid[(pdir+1)%3] == node_pos[(pdir+1)%3]) 00242 && (grid[(pdir+2)%3] == node_pos[(pdir+2)%3]) ) { 00243 involved = 1; 00244 } 00245 00246 MPI_Comm_split(comm_cart, involved, this_node, &slice_comm); 00247 MPI_Comm_rank(slice_comm, &subrank); 00248 00249 if (this_node == newroot) 00250 result = realloc(result,box_l[pdir]/lblattice.agrid*sizeof(double)); 00251 00252 //fprintf(stderr,"%d (%d,%d): result=%p vcomp=%d pdir=%d x1=%d x2=%d involved=%d\n",this_node,subrank,newroot,result,vcomp,pdir,x1,x2,involved); 00253 00254 if (involved) { 00255 00256 velprof = malloc(lblattice.grid[pdir]*sizeof(double)); 00257 00258 //dir[(pdir+1)%3] += 1; 00259 //dir[(pdir+2)%3] += 1; 00260 for (dir[pdir]=1;dir[pdir]<=lblattice.grid[pdir];dir[pdir]++) { 00261 00262 index = get_linear_index(dir[0],dir[1],dir[2],lblattice.halo_grid); 00263 lb_calc_local_fields(index, &rho, j, NULL); 00264 00265 //fprintf(stderr,"%p %d %.12e %.12e %d\n",lbfluid[0],index,rho,j[0],vcomp); 00266 00267 if (rho < ROUND_ERROR_PREC) { 00268 velprof[dir[pdir]-1] = 0.0; 00269 } else { 00270 //velprof[dir[pdir]-1] = local_j / (SQR(lbpar.agrid)*lbpar.tau); 00271 velprof[dir[pdir]-1] = j[vcomp]/rho * lblattice.agrid/lbpar.tau; 00272 //fprintf(stderr,"%f %f %f\n",velprof[dir[pdir]-1],local_j,local_rho); 00273 } 00274 00275 //if (dir[pdir]==lblattice.grid[pdir]) { 00276 // int i; 00277 // fprintf(stderr,"(%d,%d,%d)\n",dir[0],dir[1],dir[2]); 00278 // fprintf(stderr,"%d\n",lbfluid[index].boundary); 00279 // for (i=0;i<lbmodel.n_veloc;i++) fprintf(stderr,"local_n[%p][%d]=%.12e\n",lbfluid[index].n,i,lbfluid[index].n[i]+lbmodel.coeff[i][0]*lbpar.rho); 00280 // fprintf(stderr,"local_rho=%e\n",local_rho); 00281 // fprintf(stderr,"local_j=%e\n",local_j); 00282 //} 00283 00284 } 00285 00286 MPI_Gather(velprof, lblattice.grid[pdir], MPI_DOUBLE, result, lblattice.grid[pdir], MPI_DOUBLE, newroot, slice_comm); 00287 00288 free(velprof); 00289 00290 } 00291 00292 MPI_Comm_free(&slice_comm); 00293 00294 if (newroot != 0) { 00295 if (this_node == newroot) { 00296 MPI_Send(result, lblattice.grid[pdir]*node_grid[pdir], MPI_DOUBLE, 0, REQ_VELPROF, comm_cart); 00297 free(result); 00298 } 00299 if (this_node == 0) { 00300 //fprintf(stderr,"%d: I'm just here!\n",this_node); 00301 MPI_Recv(result, lblattice.grid[pdir]*node_grid[pdir], MPI_DOUBLE, newroot, REQ_VELPROF, comm_cart, &status); 00302 //fprintf(stderr,"%d: And now I'm here!\n",this_node); 00303 } 00304 } 00305 00306 if (this_node !=0) free(params); 00307 00308 } 00309 00310 #endif /* LB */ 00311
1.7.5.1