Index: /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.cpp
===================================================================
--- /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.cpp	(revision 1349)
+++ /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.cpp	(revision 1349)
@@ -0,0 +1,218 @@
+#include "distribute_file_server2.hpp"
+#include <fstream>
+#include <vector>
+#include <string>
+#include <map>
+#include <iostream>
+#include <cstdlib>
+#include <cmath>
+
+namespace xios
+{
+
+
+using namespace std ;
+
+
+void distributeFileOverServer2(int nbServers, int nGrids, SDistGrid* grids, int nFiles, SDistFile* files)
+{
+
+  double maxBandwith=0 ;
+  for(int i=0; i<nFiles; i++) if (maxBandwith<files[i].bandwith_) maxBandwith=files[i].bandwith_ ;
+  double maxMemory=0 ;
+  for(int i=0; i<nGrids; i++) if (maxMemory<grids[i].size_) maxMemory=grids[i].size_ ;
+  double T0=maxBandwith+maxMemory ;
+  
+  // initialise
+  vector<SDistServer> servers(nbServers) ;
+  for(int i=0;i<nbServers;++i) servers[i].initialize(i,nGrids, grids, nFiles,files) ;
+  
+  double p ;
+  double Em, energy, newEnergy;
+  double T, deltaE ;
+  vector<int> listFile(nFiles);
+    
+  for(int i=0; i<nFiles; ++i) servers[i%nbServers].addFile(i) ;
+
+// compute energy
+  energy=0;
+  for(int i=0;i<nbServers;++i) if (energy<servers[i].energy_) energy=servers[i].energy_ ;
+
+  int nf1,nf2,si,sj ;
+
+//  T=energy ;
+  T=T0 ;
+  int itMax=10*nFiles*nFiles ;
+
+  srand(314159) ;
+  for(int it=0;it<itMax;++it)
+  { 
+     T=T/(1+10./itMax) ;
+  // metropolis step i->j
+
+    nf1=rand()%nFiles ;
+    si=files[nf1].assignedServer_ ;
+    sj=rand()%nbServers ;
+
+    servers[si].removeFile(nf1) ;
+    servers[sj].addFile(nf1) ;
+
+    newEnergy=0;
+    for(int i=0;i<nbServers;++i) if (newEnergy<servers[i].energy_) newEnergy=servers[i].energy_ ;
+    deltaE=newEnergy-energy ;
+    
+    if (deltaE>0) 
+    {
+      p=rand()*1./RAND_MAX ;
+      if ( p > exp(-deltaE/T)) // don't accept configuration
+      {
+        servers[sj].removeFile(nf1) ;
+        servers[si].addFile(nf1) ;
+      }
+      else energy=newEnergy ;
+    }
+    else energy=newEnergy ;
+
+// metropolis step i<->j
+
+    nf1=rand()%nFiles ;
+    nf2=rand()%nFiles ;
+
+    si=files[nf1].assignedServer_ ;
+    sj=files[nf2].assignedServer_ ;
+    
+    servers[si].removeFile(nf1) ;
+    servers[sj].removeFile(nf2) ;
+    servers[si].addFile(nf2) ;
+    servers[sj].addFile(nf1) ;
+
+    newEnergy=0;
+    for(int i=0;i<nbServers;++i) if (newEnergy<servers[i].energy_) newEnergy=servers[i].energy_  ;
+    deltaE=newEnergy-energy ;
+    
+    if (deltaE>0) 
+    {
+      p=rand()*1./RAND_MAX ;
+      if ( p > exp(-deltaE/T)) // don't accept configuration
+      {
+
+        servers[si].removeFile(nf2) ;
+        servers[sj].removeFile(nf1) ;
+        servers[si].addFile(nf1) ;
+        servers[sj].addFile(nf2) ;
+      }
+      else energy=newEnergy ;
+    }
+    else energy=newEnergy ;
+
+// metropolis switch grid
+    if (it%10==0)
+    {
+      int sum=0 ;
+      while(sum==0)
+      {
+        si=rand()%nbServers ;
+        for(int i=0;i<nGrids;++i) sum+=servers[si].assignedGrid_[i] ;
+      }    
+      sj=rand()%nbServers ;
+      int numGrid=rand()%nGrids ;
+      while (servers[si].assignedGrid_[numGrid]==0) numGrid=rand()%nGrids ;  
+      
+      int nListFile=0 ;
+      for(int i=0;i<nFiles; i++)
+      {
+        if (files[i].assignedServer_==si)
+        {
+          for (int j=0;j<files[i].nbGrids_;++j)
+          {
+            if (files[i].assignedGrid_[j]==numGrid)
+            {
+              servers[si].removeFile(i) ;
+              servers[sj].addFile(i) ;
+              listFile[nListFile]=i ;
+              nListFile++ ;
+              break ;
+            }
+          }
+        }
+      }
+
+      newEnergy=0;
+      for(int i=0;i<nbServers;++i) if (newEnergy<servers[i].energy_) newEnergy=servers[i].energy_ ;
+      deltaE=newEnergy-energy ;
+    
+      if (deltaE>0) 
+      {
+        p=rand()*1./RAND_MAX ;
+        if ( p > exp(-deltaE/T)) // don't accept configuration
+        {
+
+          for(int i=0;i<nListFile;++i)
+          {
+            servers[sj].removeFile(listFile[i]) ;
+            servers[si].addFile(listFile[i]) ;
+          }
+        }
+        else energy=newEnergy ;
+      }
+      else energy=newEnergy ;
+    }  
+    
+    if (it%1000==0) cout<<"T "<<T<<"  ;  energy "<<energy<<endl ;
+  }
+}
+
+
+void SDistServer::initialize(int num, int nMaxGrid, SDistGrid* grids, int nMaxFile, SDistFile* files)
+{
+  
+   num_=num ;
+   nMaxGrid_=nMaxGrid;
+   grids_=grids ;
+   nMaxFile=nMaxFile;
+   files_=files ; 
+   energy_=0. ;
+   bandwith_=0.;
+   assignedGrid_=new int[nMaxGrid] ;
+   for(int i=0;i<nMaxGrid;++i) assignedGrid_[i]=0 ;
+}
+
+void SDistServer::finalize()
+{
+  delete [] assignedGrid_ ;
+}
+
+
+
+double SDistServer::addFile(int numFile)
+{
+  int numGrid ;
+  bandwith_+=files_[numFile].bandwith_ ;
+  files_[numFile].assignedServer_=num_ ;
+  
+  for(int i=0;i<files_[numFile].nbGrids_;i++)
+  {
+    numGrid=files_[numFile].assignedGrid_[i] ;
+    if (assignedGrid_[numGrid]==0) memory_+=grids_[numGrid].size_ ;
+    assignedGrid_[numGrid]++ ;
+  }
+  energy_=bandwith_+memory_ ; 
+  return energy_ ;
+}
+
+
+double SDistServer::removeFile(int numFile)
+{
+  int numGrid ;
+  bandwith_-=files_[numFile].bandwith_ ;
+  for(int i=0;i<files_[numFile].nbGrids_;i++)
+  {
+    numGrid=files_[numFile].assignedGrid_[i] ;
+    if (assignedGrid_[numGrid]==1) memory_-=grids_[numGrid].size_ ;
+    assignedGrid_[numGrid]-- ;
+  }
+  energy_=bandwith_+memory_ ; 
+  return energy_ ;
+}
+
+}
Index: /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.hpp
===================================================================
--- /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.hpp	(revision 1349)
+++ /XIOS/dev/XIOS_DEV_CMIP6/src/distribute_file_server2.hpp	(revision 1349)
@@ -0,0 +1,53 @@
+#ifndef __XIOS_DISTRIBUTE_FILE_SERVER2_HPP__
+#define __XIOS_DISTRIBUTE_FILE_SERVER2_HPP__
+
+#include <cstddef>
+#include <string>
+
+namespace xios
+{
+
+
+struct SDistServer ;
+struct SDistFiles ;
+struct SDistGrid ;
+
+struct SDistFile
+{
+  SDistServer* servers_ ;
+  std::string id_;
+  
+  double bandwith_ ;
+  int nbGrids_ ;
+  int* assignedGrid_ ;
+  int assignedServer_ ;
+
+} ;
+ 
+struct SDistServer
+{
+  SDistFile* files_ ;
+  SDistGrid* grids_ ;
+  
+  double energy_ ;
+  double bandwith_ ;
+  double memory_ ;
+  int  nMaxGrid_ ;
+  int* assignedGrid_ ;
+  int num_ ;
+  
+  void initialize(int num, int nMaxGrid, SDistGrid* grids, int nMaxFile, SDistFile* files) ;
+  void finalize(void) ;
+  
+  double addFile(int numFile) ;
+  double removeFile(int numFile) ;
+} ;  
+  
+struct SDistGrid
+{
+  double size_ ;
+} ;
+
+void distributeFileOverServer2(int nbServers, int nGrids, SDistGrid* grids, int nFiles, SDistFile* files);
+}
+#endif
Index: /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.cpp
===================================================================
--- /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.cpp	(revision 1348)
+++ /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.cpp	(revision 1349)
@@ -17,5 +17,7 @@
 #include "memtrack.hpp"
 #include <limits>
+#include <fstream>
 #include "server.hpp"
+#include "distribute_file_server2.hpp"
 
 namespace xios {
@@ -889,4 +891,14 @@
    void CContext::distributeFiles(void)
    {
+     bool distFileMemory=false ;
+     distFileMemory=CXios::getin<bool>("server2_dist_file_memory", distFileMemory);
+
+     if (distFileMemory) distributeFileOverMemoryBandwith() ;
+     else distributeFileOverBandwith() ;
+   }
+
+
+   void CContext::distributeFileOverBandwith(void)
+   {
      double eps=std::numeric_limits<double>::epsilon()*10 ;
      
@@ -894,4 +906,5 @@
      if (hasServer && hasClient)
      {
+       std::ofstream ofs(("distribute_file_"+getId()+".dat").c_str(), std::ofstream::out);
        int nbPools = clientPrimServer.size();
 
@@ -908,14 +921,22 @@
        double dataPerPool = 0;
        int nfield=0 ;
+       ofs<<size<<endl ;
        for (size_t i = 0; i < size; ++i)
        {
          CFile* file = this->enabledWriteModeFiles[i];
+         ofs<<file->getId()<<endl ;
          StdSize dataSize=0;
          std::vector<CField*> enabledFields = file->getEnabledFields();
          size_t numEnabledFields = enabledFields.size();
-         for (size_t j = 0; j < numEnabledFields; ++j) dataSize += enabledFields[j]->getGlobalWrittenSize() ;
-
+         ofs<<numEnabledFields<<endl ;
+         for (size_t j = 0; j < numEnabledFields; ++j)
+         {
+           dataSize += enabledFields[j]->getGlobalWrittenSize() ;
+           ofs<<enabledFields[j]->grid->getId()<<endl ;
+           ofs<<enabledFields[j]->getGlobalWrittenSize()<<endl ;
+         }
          double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
          double dataSizeSec= dataSize/ outFreqSec;
+         ofs<<dataSizeSec<<endl ;
          nfield++ ;
 // add epsilon*nField to dataSizeSec in order to  preserve reproductive ordering when sorting
@@ -958,4 +979,98 @@
      }
    }
+
+   void CContext::distributeFileOverMemoryBandwith(void)
+   {
+     // If primary server
+     if (hasServer && hasClient)
+     {
+       int nbPools = clientPrimServer.size();
+       double ratio=0.5 ;
+       ratio=CXios::getin<double>("server2_dist_file_memory_ratio", ratio);
+
+       int nFiles = this->enabledWriteModeFiles.size();
+       vector<SDistFile> files(nFiles);
+       vector<SDistGrid> grids;
+       map<string,int> gridMap ;
+       string gridId; 
+       int gridIndex=0 ;
+
+       for (size_t i = 0; i < nFiles; ++i)
+       {
+         StdSize dataSize=0;
+         CFile* file = this->enabledWriteModeFiles[i];
+         std::vector<CField*> enabledFields = file->getEnabledFields();
+         size_t numEnabledFields = enabledFields.size();
+
+         files[i].id_=file->getId() ;
+         files[i].nbGrids_=numEnabledFields;
+         files[i].assignedGrid_ = new int[files[i].nbGrids_] ;
+         
+         for (size_t j = 0; j < numEnabledFields; ++j)
+         {
+           gridId=enabledFields[j]->grid->getId() ;
+           if (gridMap.find(gridId)==gridMap.end())
+           {
+              gridMap[gridId]=gridIndex  ;
+              SDistGrid newGrid; 
+              grids.push_back(newGrid) ;
+              gridIndex++ ;
+           }
+           files[i].assignedGrid_[j]=gridMap[gridId] ;
+           grids[files[i].assignedGrid_[j]].size_=enabledFields[j]->getGlobalWrittenSize() ;
+           dataSize += enabledFields[j]->getGlobalWrittenSize() ; // usefull
+         }
+         double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
+         files[i].bandwith_= dataSize/ outFreqSec ;
+       }
+
+       double bandwith=0 ;
+       double memory=0 ;
+   
+       for(int i=0; i<nFiles; i++)  bandwith+=files[i].bandwith_ ;
+       for(int i=0; i<nFiles; i++)  files[i].bandwith_ = files[i].bandwith_/bandwith * ratio ;
+
+       for(int i=0; i<grids.size(); i++)  memory+=grids[i].size_ ;
+       for(int i=0; i<grids.size(); i++)  grids[i].size_ = grids[i].size_ / memory * (1.0-ratio) ;
+       
+       distributeFileOverServer2(nbPools, grids.size(), &grids[0], nFiles, &files[0]) ;
+
+       vector<double> memorySize(nbPools,0.) ;
+       vector< set<int> > serverGrids(nbPools) ;
+       vector<double> bandwithSize(nbPools,0.) ;
+       
+       for (size_t i = 0; i < nFiles; ++i)
+       {
+         bandwithSize[files[i].assignedServer_] += files[i].bandwith_* bandwith /ratio ;
+         for(int j=0 ; j<files[i].nbGrids_;j++)
+         {
+           if (serverGrids[files[i].assignedServer_].find(files[i].assignedGrid_[j]) == serverGrids[files[i].assignedServer_].end())
+           {
+             memorySize[files[i].assignedServer_]+= grids[files[i].assignedGrid_[j]].size_ * memory / (1.0-ratio);
+             serverGrids[files[i].assignedServer_].insert(files[i].assignedGrid_[j]) ;
+           }
+         }
+         enabledWriteModeFiles[i]->setContextClient(clientPrimServer[files[i].assignedServer_]) ;
+         delete [] files[i].assignedGrid_ ;
+       }
+
+       for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned file bandwith "<<bandwithSize[i]*86400.*4./1024/1024.<<" Mb / days"<<endl ;
+       for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned grid memory "<<memorySize[i]*100/1024./1024.<<" Mb"<<endl ;
+
+
+       for (int i = 0; i < this->enabledReadModeFiles.size(); ++i)
+       {
+         enabledReadModeFiles[i]->setContextClient(client);          
+       }
+
+   }
+   else
+   {
+     for (int i = 0; i < this->enabledFiles.size(); ++i)
+        enabledFiles[i]->setContextClient(client);
+   }
+}
+
+
 
    /*!
Index: /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.hpp
===================================================================
--- /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.hpp	(revision 1348)
+++ /XIOS/dev/XIOS_DEV_CMIP6/src/node/context.hpp	(revision 1349)
@@ -140,4 +140,7 @@
          // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
          void distributeFiles(void);
+         void distributeFileOverBandwith() ;
+         void distributeFileOverMemoryBandwith() ;
+         
 
          // Send context close definition
