Skip to content
Snippets Groups Projects
Forked from gmsh / gmsh
15646 commits behind the upstream repository.
  • Matti Pellika's avatar
    a804c7a4
    · a804c7a4
    Matti Pellika authored
    Added ability to compute the "scalar potential cuts" for homology
    generators using coreduction. Modified utils/misc/celldriver.cpp to
    demonstrate this.
    
    Added some more or less useful utility and experimental functions.
    Numerious bug fixes.
    a804c7a4
    History
    Matti Pellika authored
    Added ability to compute the "scalar potential cuts" for homology
    generators using coreduction. Modified utils/misc/celldriver.cpp to
    demonstrate this.
    
    Added some more or less useful utility and experimental functions.
    Numerious bug fixes.
celldriver.cpp 4.06 KiB
// configure, compile and install Gmsh as a library with
//
//   ./configure --disable-gui --disable-netgen --disable-chaco --prefix=/usr/local/
//   make install-lib
//
// Then compile this driver with "g++ celldriver.cpp -lGmsh -llapack -lblas -lgmp"
//
//
// This program creates .msh file chains.msh which represents the generators and
// the cuts of an two port transformer model's homology groups.


#include <stdio.h>
#include <sstream>
#include <gmsh/Gmsh.h>
#include <gmsh/GModel.h>
#include <gmsh/MElement.h>
#include <gmsh/CellComplex.h>
#include <gmsh/ChainComplex.h>

template <class TTypeA, class TTypeB>
bool convert(const TTypeA& input, TTypeB& output ){
  std::stringstream stream;
  stream << input;
  stream >> output;
  return stream.good();
}


int main(int argc, char **argv)
{
  GmshInitialize(argc, argv);
  GModel *m = new GModel();
  m->readGEO("transformer.geo");
  m->mesh(3);
  
  printf("This model has: %d GRegions, %d GFaces, %d GEdges and %d GVertices. \n" , m->getNumRegions(), m->getNumFaces(), m->getNumEdges(), m->getNumVertices());
  
  std::vector<GEntity*> domain;
  std::vector<GEntity*> subdomain;
  
  // whole model the domain
  for(GModel::riter rit = m->firstRegion(); rit != m->lastRegion(); rit++){
    GEntity *r = *rit;
    domain.push_back(r);
  }

  // the ports as subdomain
  GModel::fiter sub = m->firstFace();
  GEntity *s = *sub;
  subdomain.push_back(s);
  s = *(++sub);
  subdomain.push_back(s);
  s =*(++sub);
  subdomain.push_back(s);
  s= *(++sub);
  subdomain.push_back(s);
  
  // create a cell complex
  CellComplex* complex = new CellComplex(domain, subdomain);

  // write the cell complex to a .msh file
  complex->writeComplexMSH("chains.msh");

  printf("Cell complex of this model has: %d volumes, %d faces, %d edges and %d vertices\n",
         complex->getSize(3), complex->getSize(2), complex->getSize(1), complex->getSize(0));  
  
  // reduce the complex in order to ease homology computation
  complex->reduceComplex();
  
  // create a chain complex of a cell complex (construct boundary operator matrices)
  ChainComplex* chains = new ChainComplex(complex);
  // compute the homology using the boundary operator matrices
  chains->computeHomology();
  
  // Append the homology generators to the .msh file as post-processing views. 
  // To visualize the result, open chains.msh with Gmsh GUI and deselect all mesh
  // entities from Tools->Options->Mesh->Visibility.
  for(int j = 0; j < 4; j++){
    for(int i = 1; i <= chains->getBasisSize(j); i++){
    
      std::string generator;
      std::string dimension;
      convert(i, generator);
      convert(j, dimension);
      std::string name = dimension + "D Generator " + generator;
      
      Chain* chain = new Chain(complex->getCells(j), chains->getCoeffVector(j,i), complex, name);
      chain->writeChainMSH("chains.msh");
      delete chain;
      
    }
  }
  
  delete chains;
  
  // restore the cell complex to its prereduced state
  complex->restoreComplex();
  
  // reduce the complex by coreduction, this removes all vertices, hence 0 as an argument 
  complex->coreduceComplex(0);
  
  // create a chain complex of a cell complex (construct boundary operator matrices)
  ChainComplex* dualChains = new ChainComplex(complex);
  
  // transpose the boundary operator matrices, 
  // these are the boundary operator matrices for the dual chain complex
  dualChains->transposeHMatrices();
  
  // compute the homology of the dual complex
  dualChains->computeHomology(true);  
  
  // Append the duals of the cuts of the homology generators to the .msh file.
  for(int j = 3; j > -1; j--){
    for(int i = 1; i <= dualChains->getBasisSize(j); i++){

      std::string generator;
      std::string dimension;
      convert(i, generator);
      convert(3-(j-1), dimension);

      std::string name = dimension + "D Dual cut " + generator;
      Chain* chain = new Chain(complex->getCells(j-1), dualChains->getCoeffVector(j,i), complex, name);
                chain->writeChainMSH("chains.msh");
      delete chain;
    }
  }

  delete dualChains;

  
  delete complex;  
  delete m;
  GmshFinalize();
  
}