// GenFem - A high-level finite element library
// Copyright (C) 2010-2026 Eric Bechet
//
// See the LICENSE file for license information and contributions.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//
// Initial design: Frederic Duboeuf (rev.694)


#include "savedUnknownTerm.h"
#include "assert.h"
#include <cstdio>


template<class T> void SavedUnknownTerm<T>::get(MElement* ele, int npts, IntPt* GP, std::vector<ContainerValType> &vvals) const
{
  ContainerValType vals;
  get(ele, npts, GP, vals);

  vvals[0] = vals;
}

template<class T> void SavedUnknownTerm<T>::get(MElement* ele, int npts, IntPt* GP, ContainerValType &vals) const
{
  std::vector<Dof> D;
  fs->getKeys(ele, D);

  int nbdofs = D.size();
  vals.resize(nbdofs);
  
  int nbUnknown = 0;
  std::map<Dof, ValType>::const_iterator it;
  for (int i=0; i<nbdofs; ++i)
  {
    it = mapUnknown.find(D[i]);
    if(it != mapUnknown.end())
    {
      vals(nbUnknown) = it->second;
      ++nbUnknown;
    }
  }
  vals.resize(nbUnknown,false);
}


template<class T> void SavedUnknownTerm<T>::set(MElement* ele, int nbUnknown, std::vector<Dof> &D, ContainerValType &Dofvals)
{
  for (int i=0; i<nbUnknown; ++i)
  {
    mapUnknown[D[i]] = Dofvals(i);
  }
}


template<class T> void SavedUnknownTerm<T>::print(const char* name)
{
  printf("\n");
  printf("Print %s, size %d :\n", name, (int)mapUnknown.size());
  std::map< Dof, ValType >::const_iterator it;
  for ( it=mapUnknown.begin(); it!=mapUnknown.end(); it++)
  {
    Dof d = it->first;
    long int entity = d.getEntity();
    int type = d.getType();
    double val = it->second;
    printf(" Entity : %ld, Type : %d\n", entity, type);
    PrintOp(val);
  }
}

template<class T> bool SavedUnknownTerm<T>::printfile(const std::string &fileName, const std::ios_base::openmode mode, const int precision)
{
  std::ofstream f;
  f.open(fileName.c_str(), std::ios::out | mode);
  if (f.bad())
    return 0;

  f << std::setiosflags( std::ios::scientific ) ;
  f << std::setiosflags( std::ios::showpos ) ;
  f << std::setprecision(precision);

  int endOfName = fileName.find('.');
  std::string name = fileName.substr(0,endOfName);

  f << "Description : \n";
  f << "\n";
  f << " Class : SavedUnknownTerm \n";
  f << " Name : " << name.c_str() << "\n";
  f << " NbDof : " << size() << "\n";
  f << " ValType : " << TensorialProperties<T>::Name() << "\n";
  f << " ContainerDim : " << 1 << "\n";
  f << "\n";
  f << "\n";
  f << "Values : \n";
  f << "\n";
  typename std::map< Dof, ValType > ::const_iterator it;
  for ( it=mapUnknown.begin(); it!=mapUnknown.end(); ++it )
  {
    Dof d = it->first;
    long int entity = d.getEntity();
    int type = d.getType();
    double val = it->second;
    
    f << " Entity : " << entity << ", Type : " << type << "\n";
    f << "\n";

    int tensLength = TensorialProperties<T>::Length();
    for(int l = 0; l < tensLength; ++l)
    {
      f << "  ";
      writeTensor(val,f,l);
      f << "\n";
    }
    f << "\n";
  }
  f.close();
  return true;
}
