All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fudaa.dodico.reflux.io.INPWriterAbstract Maven / Gradle / Ivy

There is a newer version: 2.7
Show newest version
/*
 * @creation 21 mars 2003
 * @modification $Date: 2007-06-29 15:10:23 $
 * @license GNU General Public License 2
 * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne
 * @mail [email protected]
 */
package org.fudaa.dodico.reflux.io;

import gnu.trove.TDoubleHashSet;
import gnu.trove.TIntArrayList;
import gnu.trove.TIntObjectHashMap;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.fudaa.ctulu.CtuluAnalyze;
import org.fudaa.ctulu.CtuluIOOperationSynthese;
import org.fudaa.ctulu.CtuluLibMessage;
import org.fudaa.ctulu.CtuluLibString;
import org.fudaa.ctulu.ProgressionUpdater;
import org.fudaa.ctulu.fileformat.FileFormatVersionInterface;
import org.fudaa.ctulu.fileformat.FileWriteOperationAbstract;
import org.fudaa.ctulu.fileformat.FortranInterface;

import org.fudaa.dodico.commun.DodicoArrayList;
import org.fudaa.dodico.commun.DodicoLib;
import org.fudaa.dodico.dico.DicoDataType;
import org.fudaa.dodico.dico.DicoEntite;
import org.fudaa.dodico.ef.AllFrontierIteratorInterface;
import org.fudaa.dodico.ef.EfElement;
import org.fudaa.dodico.ef.EfElementType;
import org.fudaa.dodico.ef.EfGridInterface;
import org.fudaa.dodico.fortran.FortranWriter;
import org.fudaa.dodico.h2d.H2dNodalPropertyMixte;
import org.fudaa.dodico.h2d.H2dTimeStepGroup;
import org.fudaa.dodico.h2d.reflux.H2dRefluxBordIndexGeneral;
import org.fudaa.dodico.h2d.reflux.H2dRefluxBoundaryCondition;
import org.fudaa.dodico.h2d.resource.H2dResource;
import org.fudaa.dodico.h2d.type.H2dBcType;
import org.fudaa.dodico.h2d.type.H2dRefluxBoundaryType;
import org.fudaa.dodico.h2d.type.H2dResolutionSchemaType;
import org.fudaa.dodico.h2d.type.H2dVariableType;
import org.fudaa.dodico.mesure.EvolutionReguliere;
import org.fudaa.dodico.mesure.EvolutionReguliereAbstract;

/**
 * @author deniger
 * @version $Id: INPWriterAbstract.java,v 1.1 2007-06-29 15:10:23 deniger Exp $
 */
public abstract class INPWriterAbstract extends FileWriteOperationAbstract {

  private static class CLGroup {

    H2dBcType clType_;
    double valeur_;
    H2dVariableType variable_;

    /**
     * tout a null.
     */
    public CLGroup() {
    }

    /**
     * @param _c le groupe pour initialiser.
     */
    public CLGroup(final CLGroup _c) {
      variable_ = _c.variable_;
      clType_ = _c.clType_;
      valeur_ = _c.valeur_;
    }

    /**
     * @param _v la variable
     * @param _t le type
     * @param _valeur la valeur.
     */
    public CLGroup(final H2dVariableType _v, final H2dBcType _t, final double _valeur) {
      variable_ = _v;
      clType_ = _t;
      valeur_ = _valeur;
    }

    /**
     * Test la variable,type et valeur.
     */
    @Override
    public boolean equals(final Object _obj) {
      if (_obj == this) {
        return true;
      }
      if (_obj instanceof CLGroup) {
        final CLGroup g = (CLGroup) _obj;
        return (variable_ == g.variable_) && (clType_ == g.clType_) && (valeur_ == g.valeur_);
      }
      return false;
    }

    /**
     * @return le type
     */
    public H2dBcType getClType() {
      return clType_;
    }

    /**
     * @return la valeur
     */
    public double getValeur() {
      return valeur_;
    }

    /**
     * @return la variable
     */
    public H2dVariableType getVariable() {
      return variable_;
    }

    /**
     * en accord avec la methode equals.
     */
    @Override
    public int hashCode() {
      return clType_.hashCode() + variable_.hashCode() + (int) Double.doubleToLongBits(valeur_);
    }

    /**
     * @param _type nouveau type
     */
    public void setClType(final H2dBcType _type) {
      clType_ = _type;
    }

    /**
     * @param _d nouvelle valeur.
     */
    public void setValeur(final double _d) {
      valeur_ = _d;
    }

    /**
     * @param _type la variable
     */
    public void setVariable(final H2dVariableType _type) {
      variable_ = _type;
    }

    @Override
    public String toString() {
      return variable_ + CtuluLibString.ESPACE + clType_ + "( value= " + valeur_ + ")";
    }
  }

  private interface ElementGroup {

    /**
     * @param _l la liste qui recevra toutes les evolutions utilisees
     */
    void addEvolInList(List _l);

    /**
     * @param _fmtType le format
     * @param _fmtValeur les valeur
     * @throws IOException
     */
    void print(int[] _fmtType, int[] _fmtValeur) throws IOException;
  }

  private class ElementGroupBord implements ElementGroup {

    List evols_;
    H2dBcType rugositeType_;
    double rugositeValeur_;

    /**
     * Rien.
     */
    public ElementGroupBord() {
    }

    /**
     * @param _t type
     * @param _v valeur
     * @param _evol evolution
     */
    public ElementGroupBord(final H2dBcType _t, final double _v, final EvolutionReguliereAbstract _evol) {
      rugositeType_ = _t;
      rugositeValeur_ = _v;
      evols_ = new ArrayList();
      if (_evol != null) {
        evols_.add(_evol);
      }
    }

    /**
     * @param _evol l'evolution a ajouter
     */
    public void add(final EvolutionReguliereAbstract _evol) {
      if (_evol != null) {
        evols_.add(_evol);
      }
    }

    @Override
    public void addEvolInList(final List _l) {
      if ((evols_ != null) && (evols_.size() > 0)) {
        _l.addAll(evols_);
      }
    }

    @Override
    public boolean equals(final Object _obj) {
      if (_obj == this) {
        return true;
      }
      if (_obj instanceof ElementGroupBord) {
        final ElementGroupBord b = (ElementGroupBord) _obj;
        return ((b.rugositeType_ == rugositeType_) && (b.rugositeValeur_ == rugositeValeur_));
      }
      return false;
    }

    @Override
    public int hashCode() {
      return (int) (rugositeType_.hashCode() + Double.doubleToLongBits(rugositeValeur_));
    }

    @Override
    public void print(final int[] _fmtType, final int[] _fmtValeur) throws IOException {
      out_.intField(0, version_.getCode(rugositeType_));
      out_.writeFields(_fmtType);
      out_.doubleField(0, rugositeValeur_);
      out_.writeFields(_fmtValeur);
    }

    @Override
    public String toString() {
      return rugositeType_ + CtuluLibString.ESPACE + rugositeValeur_;
    }
  }

  private class ElementGroupFond implements ElementGroup {

    List[] evols_;
    H2dBcType[] types_;
    double[] valeurs_;

    /**
     * Les 3 tableaux doivent etre de meme taille.
     *
     * @param _type types
     * @param _v valeurs
     * @param _evol evolutions
     */
    public ElementGroupFond(final H2dBcType[] _type, final double[] _v, final EvolutionReguliereAbstract[] _evol) {
      types_ = _type;
      valeurs_ = _v;
      if (valeurs_.length != types_.length) {
        throw new IllegalArgumentException("not the same length");
      }
      if (valeurs_.length != _evol.length) {
        throw new IllegalArgumentException("not the same length");
      }
      evols_ = new ArrayList[valeurs_.length];
      for (int i = valeurs_.length - 1; i >= 0; i--) {
        evols_[i] = new ArrayList();
        if (_evol[i] != null) {
          evols_[i].add(_evol[i]);
        }
      }
    }

    /**
     * @param _evol les evolutions a ajouter
     */
    public void add(final EvolutionReguliereAbstract[] _evol) {
      for (int i = valeurs_.length - 1; i >= 0; i--) {
        if (_evol[i] != null) {
          evols_[i].add(_evol[i]);
        }
      }
    }

    @Override
    public void addEvolInList(final List _l) {
      for (int i = 0; i < evols_.length; i++) {
        if ((evols_[i] != null) && (evols_[i].size() > 0)) {
          _l.addAll(evols_[i]);
        }
      }
    }

    @Override
    public boolean equals(final Object _obj) {
      if (_obj == this) {
        return true;
      }
      if (_obj instanceof ElementGroupFond) {
        final ElementGroupFond b = (ElementGroupFond) _obj;
        final int nb = types_.length;
        if (b.types_.length != nb) {
          return false;
        }
        for (int i = nb - 1; i >= 0; i--) {
          if (types_[i] != b.types_[i]) {
            return false;
          }
          if (valeurs_[i] != b.valeurs_[i]) {
            return false;
          }
        }
        return true;
      }
      return false;
    }

    @Override
    public int hashCode() {
      int r = 0;
      for (int i = types_.length - 1; i >= 0; i--) {
        r += (int) (types_[i].hashCode() + Double.doubleToLongBits(valeurs_[i]));
      }
      return r;
    }

    @Override
    public void print(final int[] _fmtType, final int[] _fmtValeur) throws IOException {
      final int nb = types_.length;
      for (int i = 0; i < nb; i++) {
        out_.intField(i, version_.getCode(types_[i]));
      }
      out_.writeFields(_fmtType);
      for (int i = 0; i < nb; i++) {
        out_.doubleField(i, valeurs_[i]);
      }
      out_.writeFields(_fmtValeur);
    }

    @Override
    public String toString() {
      final StringBuffer b = new StringBuffer(100);
      final int nb = types_.length;
      for (int i = 0; i < nb; i++) {
        b.append(i).append(": ").append(types_[i]).append(CtuluLibString.ESPACE).append(valeurs_[i]);
      }
      return b.toString();
    }
  }
  String baseDir_;
  String lineSep_;
  FortranWriter out_;
  RefluxINPV5P0Version version_;

  /**
   * @param _f version a ajouter.
   */
  public INPWriterAbstract(final RefluxINPV5P0Version _f) {
    version_ = _f;
    lineSep_ = CtuluLibString.LINE_SEP;
  }

  private void manageClGroup(final H2dRefluxBoundaryCondition _cl, final int _nbCl, final H2dVariableType _varType,
          final H2dBcType _type, final double _valeur, final Map _clInt, final CLGroup _temp) {
    _temp.setClType(_type);
    _temp.setValeur(_valeur);
    _temp.setVariable(_varType);
    List l = (ArrayList) _clInt.get(_temp);
    if (l == null) {
      l = new ArrayList(_nbCl);
      l.add(_cl);
      _clInt.put(new CLGroup(_temp), l);
    } else {
      l.add(_cl);
    }
  }
  INPInterface inter_;
  int nbPts_;
  EfGridInterface grid_;
  ProgressionUpdater up_;
  DodicoArrayList clCourbes_;
  DodicoArrayList pnCourbes_;

  private void writeINP(final INPInterface _inter) {
    if (!testConfig(_inter)) {
      return;
    }

    initFields(_inter);
    try {
      out_.setLineSeparator(lineSep_);
      // Entete
      writeBlocEntete();
      // IMPRESSION
      final List impressionsList = writeBlocImpression();
      // BLOC DATA
      writeBlocData();
      // BLOC COOR

      writeBlocCoor();
      // BLOC DLPN
      writeBlocDLPN();
      // BLOC COND
      final TIntObjectHashMap globIdxBc = writeBlocCOND();
      if (globIdxBc == null) {
        return;
      }
      // BLOC PRND
      writeBlocPRND(globIdxBc);

      boolean ok = computeGroupElem();
      if (!ok) {
        return;
      }
      // Bloc ELEM Definit les elements T6 puis T3
      writeBlocElem();

      // Bloc TPEL Definit pour chaque element son type. Les elements T6 ne sont pas interressant: toujours de type 5 :
      // on les ignore. Par contre, il faut connaitre le type des elements de bord.
      writeBlocTPEL();
      // Bloc PREL Le bloc des proprietes elementaires. Donne pour chaque elements, le groupe de prop correspondant. Si
      // aucun, l'entier 0 est utilise.
      // ElementGroupFond->TIntArrayList
      writeBlocPREL();
      // Bloc FICHIER Les fichiers entree,sortie, courbes transitoires.
      writeBlocFICHIER();
      // Bloc SOLR
      writeBlocSOLR();
      // Bloc CRAD
      writeBlocCRAD();
      // Bloc VENT
      writeBlocVENT();
      // Bloc IMPRESSION bis
      writeBlocIMPRESSION(impressionsList);
      // Bloc TRANS ignore
      // Bloc FLUT
      writeBlocFLUT();
    } catch (final IOException _e) {
      analyze_.manageException(_e);
    }
    // cl

    final double maxTime = H2dTimeStepGroup.getMaxTime(inter_.getTimeBeginningForTrans(), inter_.getGroupePasTemps());
    final double minTime = H2dTimeStepGroup.getMinTime(inter_.getTimeBeginningForTrans(), inter_.getGroupePasTemps());
    StringBuffer nameEvolBad = writeClCourbe(maxTime, minTime);
    // pn
    nameEvolBad = writePnCourbes(maxTime, minTime, nameEvolBad);
    if (nameEvolBad != null) {
      analyze_.addError(H2dResource.getS("Les courbes suivantes ne contiennent pas les bornes de la simulation")
              + CtuluLibString.LINE_SEP + nameEvolBad.toString(), 0);
    }
  }

  private StringBuffer writePnCourbes(final double _maxTime, final double _minTime, StringBuffer _nameEvolBad) {
    StringBuffer nameEvolBad = _nameEvolBad;
    if (pnCourbes_.size() > 0) {
      final double[] timeStep = getTimesSteps(pnCourbes_, _maxTime, _minTime);
      final Map oldEvolNewEvol = new HashMap(pnCourbes_.size());
      final String ficPn = version_.getPnTransitoireFichier(inter_.getFichiers());
      if (ficPn == null) {
        analyze_.addError(H2dResource.getS("Le fichier des proprietes nodales transitoires est introuvable (donn?es non enregistr?es)"), 0);
      } else {
        final File fic = new File(baseDir_, ficPn);
        if (CtuluLibMessage.DEBUG) {
          CtuluLibMessage.debug("write " + fic.getAbsolutePath());
        }
        final int n = pnCourbes_.size();
        final EvolutionReguliere[] evols = new EvolutionReguliere[n];
        for (int i = 0; i < n; i++) {
          final EvolutionReguliere e = (EvolutionReguliere) pnCourbes_.get(i);
          if (oldEvolNewEvol.containsKey(e)) {
            evols[i] = (EvolutionReguliere) oldEvolNewEvol.get(e);
          } else {
            if ((!e.isInclude(_minTime)) || (!e.isInclude(_maxTime))) {
              if (nameEvolBad == null) {
                nameEvolBad = new StringBuffer();
                nameEvolBad.append(e.getNom());
              } else {
                nameEvolBad.append(", ").append(e.getNom());
              }
            }
            evols[i] = e.createTimeEvolutionFromInterpolation(timeStep);
            oldEvolNewEvol.put(e, evols[i]);
          }
        }
        final CLVWriter w = version_.createCLVWriter();
        analyze_.merge(w.write(evols, fic, progress_).getAnalyze());
      }
    }
    return nameEvolBad;
  }

  private StringBuffer writeClCourbe(final double _maxTime, final double _minTime) {
    StringBuffer nameEvolBad = null;
    if (clCourbes_.size() > 0) {
      final double[] timeStep = getTimesSteps(clCourbes_, _maxTime, _minTime);
      final Map oldEvolNewEvol = new HashMap(clCourbes_.size() * 2);
      final String ficCl = version_.getCLTransitoireFichier(inter_.getFichiers());
      if (ficCl == null) {
        analyze_.addError(H2dResource.getS("Le fichier des conditions limites transitoires est introuvable (donn?es non enregistr?es)"), 0);
      } else {
        final File fic = new File(baseDir_, ficCl);
        if (CtuluLibMessage.DEBUG) {
          CtuluLibMessage.debug("write " + fic.getAbsolutePath());
        }
        final int n = clCourbes_.size();
        final EvolutionReguliere[] evols = new EvolutionReguliere[n];
        for (int i = 0; i < n; i++) {
          final EvolutionReguliere eTransitoire = (EvolutionReguliere) clCourbes_.get(i);
          if (oldEvolNewEvol.containsKey(eTransitoire)) {
            evols[i] = (EvolutionReguliere) oldEvolNewEvol.get(eTransitoire);
          } else {
            if ((!eTransitoire.isInclude(_minTime)) || (!eTransitoire.isInclude(_maxTime))) {
              if (nameEvolBad == null) {
                nameEvolBad = new StringBuffer();
                nameEvolBad.append(eTransitoire.getNom());
              } else {
                nameEvolBad.append(", ").append(eTransitoire.getNom());
              }
            }
            evols[i] = eTransitoire.createTimeEvolutionFromInterpolation(timeStep);
            oldEvolNewEvol.put(eTransitoire, evols[i]);
          }
        }
        final CLVWriter w = version_.createCLVWriter();
        analyze_.merge(w.write(evols, fic, progress_).getAnalyze());
      }
    }
    return nameEvolBad;
  }

  private void writeBlocFLUT() throws IOException {
    out_.writeln(version_.getFLUT());
    out_.writeln(inter_.getTypeProjet().getRefluxId());
    out_.println(); // 2 lignes blanches pour faire joli
    out_.println();
    final H2dTimeStepGroup[] gpTemps = inter_.getGroupePasTemps();
    final int nbGp = gpTemps.length;
    final int[] fmt = version_.getCoefficientContributionFormat();
    final int max = fmt.length;
    double t = inter_.getTimeBeginInForInpFile();
    // v?rification surement inutile ....
    if (t < 0) {
      t = 0;
    }
    final Map entiteValue = inter_.getEntiteValue();
    for (int i = 0; i < nbGp; i++) {
      out_.doubleField(1, t);
      // pour le groupe suivant
      t += gpTemps[i].getTimeLength();
      out_.intField(0, gpTemps[i].getNbPasTemps());
      out_.writeFields(version_.getFLUTNbPasTemps());
      out_.println();
      out_.writeln(inter_.getTypeProjet().getRefluxId());
      final H2dResolutionSchemaType schema = gpTemps[i].getSchema();
      if (schema == H2dResolutionSchemaType.STATIONNAIRE) {
        out_.writeln(schema.getRefluxId());
      } else {
        out_.stringField(0, schema.getRefluxId());
        out_.doubleField(1, gpTemps[i].getValeurPasTemps());
        out_.doubleField(2, gpTemps[i].getCoefSchema());
        out_.writeFields(version_.getFLUTSchemaResolutionFormat());
      }
      out_.stringField(0, gpTemps[i].getMethode().getRefluxId());
      out_.doubleField(1, gpTemps[i].getRelaxation());
      out_.doubleField(2, gpTemps[i].getPrecision());
      out_.doubleField(3, gpTemps[i].getPrecisionBancCouvrantDecouvrant());
      out_.intField(4, gpTemps[i].getNombreIterationMax());
      out_.writeFields(version_.getFLUTMethodeResolutionFormat());
      int indexEnCours = 1;
      final int itemp2 = version_.getCoefContributionNb();
      out_.stringField(0, version_.getFLUTCoefficientContribution());
      for (int j = 0; j < itemp2; j++) {
        if (indexEnCours == max) {
          indexEnCours = 1;
          out_.writeFields(fmt);
          out_.stringField(0, CtuluLibString.ESPACE);
        }
        final DicoEntite ent = version_.getCoefContribution(j);
        double d = 0;
        if (ent == null) {
          analyze_.addError(DodicoLib.getS("Erreur interne"), 0);
        } else {
          String sValue = (String) entiteValue.get(ent);
          if (sValue == null) {
            sValue = ent.getDefautValue();
          }
          d = Double.parseDouble(sValue);
          if (ent == version_.getSollicitationRadiation() && inter_.contientRadiations() && d <= 0) {
            d = 1;
          } else if (ent == version_.getSollicitationVent() && inter_.contientVent() && d <= 0) {
            d = 1;
          }

        }
        out_.doubleField(indexEnCours++, d);
      }
      out_.writeFields(fmt);
      out_.stringField(0, version_.getFLUTImpression());
      out_.intField(1, gpTemps[i].getFrequenceImpression());
      out_.writeFields(version_.getFLUTFreqImpressionFormat());
      out_.println();
      out_.println();
      out_.println();
    }
    out_.println();
    out_.println();
    out_.writeln(version_.getSTOP());
  }

  private void writeBlocIMPRESSION(final List _impressionsList) throws IOException {
    final int itemp1 = _impressionsList.size();
    for (int i = 0; i < itemp1; i++) {
      out_.writeln((String) _impressionsList.get(i));
    }
    if (itemp1 > 0) {
      out_.println();
    }
  }

  private void writeBlocVENT() throws IOException {
    if (inter_.contientVent()) {
      out_.writeln(version_.getVENT());
      out_.stringField(0, inter_.getTypeProjet().getRefluxId());
      out_.intField(1, inter_.isVentLecturePasDeTemps() ? 1 : 0);
      out_.writeFields(version_.getVENTFormat());
      out_.println();
    }
  }

  private void writeBlocCRAD() throws IOException {
    if (inter_.contientRadiations()) {
      out_.writeln(version_.getCRAD());
      out_.stringField(0, inter_.getTypeProjet().getRefluxId());
      out_.intField(1, inter_.isRadiationsLecturePasDeTemps() ? 1 : 0);
      out_.writeFields(version_.getCRADFormat());
      out_.println();
    }
  }

  private void writeBlocSOLR() throws IOException {
    if (inter_.contientSollicitationsReparties()) {
      out_.writeln(version_.getSOLR());
      out_.stringField(0, inter_.getTypeProjet().getRefluxId());
      out_.intField(1, 1);
      out_.writeFields(version_.getSOLRFormat());
      out_.println();
    }
  }

  private void writeBlocFICHIER() throws IOException {
    final String[] fics = inter_.getFichiers();
    for (int i = 0; i < fics.length; i++) {
      out_.writeln(version_.getFICHIER() + CtuluLibString.ESPACE + fics[i]);
    }
    out_.println();
  }
  TIntArrayList grpIdx_;
  List grpFond_;

  private boolean writeBlocPREL() throws IOException {
    // nbPropElem = nbElem + nbT3bord;
    writeBlocPRELEntete();
    writeBlocPRELIdxs();
    up_.majProgessionStateOnly(version_.getPREL());
    final int[] fmt = version_.getGroupElemCodeFormat();
    int nbPropElem = grpFond_.size();
    final H2dNodalPropertyMixte[] gpEl = inter_.getPropElementaires();
    final int[] fmt2 = version_.getHuitDoubleFormat();
    ElementGroup egp;
    up_.setValue(10, nbPropElem);
    for (int i = 0; i < nbPropElem; i++) {
      egp = (ElementGroup) grpFond_.get(i);
      egp.print(fmt, fmt2);
      egp.addEvolInList(pnCourbes_);
      up_.majAvancement();
    }
    final Double viscosityVal = H2dTimeStepGroup.isViscosityTransitUsed(inter_.getGroupePasTemps());
    // on ecrit la viscosit? de transit dans un groupe ? part ....
    if (viscosityVal != null) {
      final int code = version_.getCode(H2dBcType.PERMANENT);
      for (int i = gpEl.length - 1; i >= 0; i--) {
        out_.intField(i, code);
      }
      out_.writeFields(fmt);
      for (int i = gpEl.length - 1; i > 0; i--) {
        out_.doubleField(i, 0d);
      }
      out_.doubleField(0, viscosityVal.doubleValue());
      out_.writeFields(fmt2);

    }
    out_.println();
    out_.println();
    return true;
  }

  protected abstract void writeBlocPRELIdxs() throws IOException;

  protected abstract void writeBlocPRELEntete() throws IOException;

  protected int getNbGroupWithViscosity() {
    int nbGroupe = grpFond_.size();
    if (H2dTimeStepGroup.isViscosityTransitUsed(inter_.getGroupePasTemps()) != null) {
      nbGroupe++;
    }
    return nbGroupe;
  }
  boolean gpElemDone_;

  private boolean computeGroupElem() {
    if (gpElemDone_) {
      return true;
    }
    up_.majProgessionStateOnly(H2dResource.getS("groupes ?l?mentaires"));
    final H2dRefluxBordIndexGeneral[] bd = inter_.getBords();
    final int nbElt = grid_.getEltNb();
    final int nbBd = bd == null ? 0 : bd.length;
    final H2dNodalPropertyMixte[] props = inter_.getPropElementaires();
    int nbProps = props.length;
    int nbEltTotal = nbElt + nbBd;
    grpIdx_ = new TIntArrayList(nbEltTotal);
    grpFond_ = new ArrayList(20);

    // les groupes de fond.
    final H2dBcType[] types = new H2dBcType[nbProps];
    final double[] vals = new double[nbProps];
    final EvolutionReguliereAbstract[] evols = new EvolutionReguliere[nbProps];
    final ElementGroupFond gpFond = new ElementGroupFond(types, vals, evols);
    // l'ordre est important car les courbes transitoires sont
    // ajoutees dans l'ordre.
    up_.setValue(5, nbElt, 0, 50);
    for (int i = 0; i < nbElt; i++) {
      for (int j = 0; j < nbProps; j++) {
        types[j] = props[j].getTypeForEltIdx(i);
        if (types[j] == H2dBcType.TRANSITOIRE) {
          final EvolutionReguliereAbstract evol = props[j].getTransitoireEvol(i);
          if (evol == null) {
            analyze_.addFatalError(H2dResource.getS("Courbe transitoire non trouv?e") + "("
                    + H2dResource.getS("groupe") + ": " + props[j] + CtuluLibString.ESPACE + H2dResource.getS("?l?ment")
                    + i + ")");
            return false;
          }
          // pnTransitoireCourbeList.add(evol);
          vals[j] = 0d;
          evols[j] = evol;
        } else if (types[j] == H2dBcType.LIBRE) {
          vals[j] = 0d;
          evols[j] = null;
        } else {
          vals[j] = props[j].getPermanentValueFor(i);
          evols[j] = null;
        }
      }
      // idxInGp represente l'indice de tempGpFond dans les groupes
      // deja cree. Si negatif, aucun groupe ne correspond.
      final int idxInGpD = grpFond_.indexOf(gpFond);
      if (idxInGpD >= 0) {
        grpIdx_.add(idxInGpD);
        ((ElementGroupFond) grpFond_.get(idxInGpD)).add(evols);
      } else {
        final double[] tempValNew = new double[vals.length];
        System.arraycopy(vals, 0, tempValNew, 0, vals.length);
        final H2dBcType[] tempClNew = new H2dBcType[vals.length];
        System.arraycopy(types, 0, tempClNew, 0, vals.length);
        grpIdx_.add(grpFond_.size());
        grpFond_.add(new ElementGroupFond(tempClNew, tempValNew, evols));
      }
      up_.majAvancement();
    }
    if (nbBd > 0) {
      final List groupeBord = new ArrayList(20);
      final ElementGroupBord tempBord = new ElementGroupBord();
      EvolutionReguliereAbstract evol;
      // l'offset pour les numeros de groupes pour les elements
      // de fond.
      final int idxCurrent = grpFond_.size();
      up_.setValue(5, nbBd, 50, 50);
      up_.majProgessionStateOnly();
      for (int i = 0; i < nbBd; i++) {
        if (bd != null && bd[i].getBordType() == H2dRefluxBoundaryType.SOLIDE_FROTTEMENT) {
          tempBord.rugositeType_ = bd[i].getRugositeType();
          tempBord.rugositeValeur_ = bd[i].getRugosite();
          if (tempBord.rugositeType_ == H2dBcType.TRANSITOIRE) {
            evol = bd[i].getRugositeTransitoireCourbe();
            if (evol == null) {
              analyze_.addFatalError(H2dResource.getS("Courbe transitoire non trouv?e") + "(" + bd[i]
                      + CtuluLibString.ESPACE + i + ")");
              return false;
            }
          } else {
            evol = null;
          }
          final int item = groupeBord.indexOf(tempBord);
          if (item >= 0) {
            grpIdx_.add(item + idxCurrent);
            if (evol != null) {
              ((ElementGroupBord) groupeBord.get(item)).add(evol);
            }
          } else {
            final ElementGroupBord tempGpBordNew = new ElementGroupBord(tempBord.rugositeType_,
                    tempBord.rugositeValeur_, evol);
            grpIdx_.add(groupeBord.size() + idxCurrent);
            groupeBord.add(tempGpBordNew);
          }
        } // le groupe 0 pour les T3 non solide avec frottement
        else {
          grpIdx_.add(0);
        }
        up_.majAvancement();
      }
      if (groupeBord.size() > 0) {
        grpFond_.addAll(groupeBord);
      }
    }
    if (nbEltTotal != grpIdx_.size()) {
      analyze_.addFatalError(H2dResource.getS("Des ?l?ments ne sont pas sp?cifi?s dans des groupes de propri?t?s"));
      return false;
    }
    gpElemDone_ = true;
    return true;
  }

  protected abstract void writeBlocTPEL() throws IOException;

  private void writeBlocElem() throws IOException {
    up_.majProgessionStateOnly(version_.getELEM());
    writeBlocElemEntete();
    final int nbEle = grid_.getEltNb();
    final H2dRefluxBordIndexGeneral[] bdT3 = inter_.getBords();
    final int nbT3bord = bdT3 == null ? 0 : bdT3.length;
    final int[] fmt = version_.getELEMValeurFormat();
    final int tailleBord = version_.getELEMTailleBord();
    final int tailleFond = version_.getELEMTailleFond();
    final int offset = fmt == null ? 1 : 0;
    up_.setValue(10, nbEle + nbT3bord);
    for (int i = 0; i < nbEle; i++) {
      final EfElement el = grid_.getElement(i);
      for (int j = 0; j < tailleFond; j++) {
        out_.intField(j + offset, el.getPtIndex(j) + 1);
      }
      finishEltLine(i, tailleFond);
      if (fmt == null) {
        out_.writeFields();
      } else {
        out_.writeFields(fmt);
      }
      up_.majAvancement();
    }
    if (bdT3 != null) {
      for (int i = 0; i < nbT3bord; i++) {
        final H2dRefluxBordIndexGeneral bdgi = bdT3[i];
        for (int j = 0; j < tailleBord; j++) {
          out_.intField(j + offset, bdgi.getIndex()[j] + 1);
        }
        finishEltBordLine(i, bdgi, tailleFond);
        if (fmt == null) {
          out_.writeFields();
        } else {
          out_.writeFields(fmt);
        }
        up_.majAvancement();
      }

    }
    if (fmt != null) {
      out_.println();
    }
  }

  protected abstract void finishEltLine(int _idxEle, int _tailleElem);

  /**
   * @param _idxBordEle : c'est l'indice du L3 attention
   * @param _bd
   * @param _tailleElem
   */
  protected abstract void finishEltBordLine(int _idxBordEle, H2dRefluxBordIndexGeneral _bd, int _tailleElem);

  protected abstract void writeBlocElemEntete() throws IOException;

  protected abstract void writeBlocPRND(final TIntObjectHashMap _globIdxBc) throws IOException;

  private TIntObjectHashMap writeBlocCOND() throws IOException {
    up_.majProgessionStateOnly(version_.getCOND());
    out_.stringField(0, version_.getCOND());
    out_.writeFields(version_.getBlocSimpleFormat());
    // H2dRefluxConditionLimite[] cl= inter_.getConditionLimite();
    final int nbCl = grid_.getFrontiers().getNbTotalPt();
    // On construit des groupes pour les conditions limites.
    // Chaque groupe donne une caracteristique precise.
    final Map clGroupeCL = new HashMap(nbCl / 2);
    CLGroup temp = new CLGroup();
    final TIntObjectHashMap globIdxBc = new TIntObjectHashMap(grid_.getFrontiers().getNbTotalPt());
    int k = 0;
    for (AllFrontierIteratorInterface it = grid_.getFrontiers().getAllFrontierIterator(); it.hasNext();) {
      final H2dRefluxBoundaryCondition cli = inter_.getConditionLimite(k++);
      if (cli == null) {
        continue;
      }
      it.next();
      globIdxBc.put(cli.getIndexPt(), cli);
      // h
      if (cli.getHType() != H2dBcType.LIBRE) {
        manageClGroup(cli, nbCl, H2dVariableType.COTE_EAU, cli.getHType(), cli.getH(), clGroupeCL, temp);
      }
      // u
      if (cli.getUType() != H2dBcType.LIBRE) {
        manageClGroup(cli, nbCl, H2dVariableType.VITESSE_U, cli.getUType(), cli.getU(), clGroupeCL, temp);
      }
      // v
      if (cli.getVType() != H2dBcType.LIBRE) {
        manageClGroup(cli, nbCl, H2dVariableType.VITESSE_V, cli.getVType(), cli.getV(), clGroupeCL, temp);
      }
    }
    up_.setValue(4, clGroupeCL.size(), 20, 80);
    up_.majProgessionStateOnly();
    for (final Iterator it = clGroupeCL.entrySet().iterator(); it.hasNext();) {
      final Map.Entry e = (Map.Entry) it.next();
      temp = (CLGroup) e.getKey();
      final int pos = version_.getPositionForCond(temp.getVariable());
      final boolean isTransitoire = (temp.getClType() == H2dBcType.TRANSITOIRE);
      for (int i = 2; i >= 0; i--) {
        if (i == pos) {
          out_.intField(pos, version_.getCode(temp.getClType()));
        } else {
          out_.intField(i, 0);
        }
      }
      out_.writeFields(version_.getCONDCodeFormat());
      for (int i = 2; i >= 0; i--) {
        if (i == pos) {
          out_.doubleField(pos, temp.getValeur());
        } else {
          out_.doubleField(i, 0d);
        }
      }
      out_.writeFields(version_.getTroisDoubleFormat());
      final List l = (ArrayList) e.getValue();
      Collections.sort(l);
      int indexEnCoursCOND = 0;
      // pour le zero final
      final int nbl = l.size() + 1;
      final int[] fmtCOND = version_.getCONDNoeudIdxFormat();
      final int maxInitCOND = fmtCOND.length;
      int maxEnCoursCOND = maxInitCOND;
      while (indexEnCoursCOND < nbl) {
        if ((nbl - indexEnCoursCOND) < maxInitCOND) {
          maxEnCoursCOND = nbl - indexEnCoursCOND;
        }
        // l'ordre est important car cl transitoire ajoute en meme temps.
        for (int i = 0; i < maxEnCoursCOND; i++) {
          // le zero final
          if (indexEnCoursCOND + i == nbl - 1) {
            out_.intField(i, 0);
          } else {
            // tempInt est l'indice du point considere
            final H2dRefluxBoundaryCondition cli = (H2dRefluxBoundaryCondition) l.get(indexEnCoursCOND + i);
            // les indices commencent a 1.
            out_.intField(i, cli.getIndexPt() + 1);
            if (isTransitoire) {
              final EvolutionReguliereAbstract evol = cli.getEvolution(temp.getVariable());
              if (evol == null) {
                analyze_.addFatalError(DodicoLib.getS("Erreur interne"), out_.getLineNumber());
                analyze_.addInfo(H2dResource.getS("Courbe transitoire non trouv?e") + " " + cli, out_.getLineNumber());
                return null;
              }
              clCourbes_.add(evol);
            }
          }
        }
        indexEnCoursCOND += maxEnCoursCOND;
        out_.writeFields(fmtCOND);
      }
      up_.majAvancement();
    }
    out_.println();
    out_.println();
    return globIdxBc;
  }

  protected abstract void writeBlocDLPN() throws IOException;

  protected abstract void writeBlocCoor() throws IOException;

  private void initFields(final INPInterface _inter) {
    inter_ = _inter;
    grid_ = inter_.getGrid();
    nbPts_ = grid_.getPtsNb();
    up_ = new ProgressionUpdater(progress_);
    clCourbes_ = new DodicoArrayList();
    pnCourbes_ = new DodicoArrayList();
  }

  protected abstract void writeBlocData() throws IOException;

  private List writeBlocImpression() throws IOException {
    final List impressionsList = new ArrayList();
    // DicoModelAbstract dico= version_.getDico();
    for (final Iterator it = inter_.getEntiteValue().entrySet().iterator(); it.hasNext();) {
      final Map.Entry e = (Map.Entry) it.next();
      final DicoEntite ent = (DicoEntite) e.getKey();
      final String val = (String) e.getValue();
      if (((ent.getRubrique().equals("Impression")) || (ent.getRubrique().equals("Print")))
              && (DicoDataType.Binaire.getValue(val))) {
        final String s = version_.getIMPRESSION() + CtuluLibString.ESPACE + ent.getNom();
        out_.writeln(s);
        impressionsList.add(s);
      }
    }
    if (impressionsList.size() > 0) {
      out_.println();
    }
    return impressionsList;
  }

  private void writeBlocEntete() throws IOException {
    out_.writeln(version_.getEnteteSeparateur());
    out_.writeln(CtuluLibString.ESPACE + H2dResource.getS("Description : Fichier d'entree de REFLUX"));
    out_.writeln(CtuluLibString.ESPACE + version_.getENTETEVersionLineStart() + ": "
            + version_.getENTETEVersionPrefixe() + CtuluLibString.ESPACE + inter_.getVersion());
    out_.writeln(version_.getEnteteSeparateur());
    out_.println();
  }

  private boolean testConfig(final INPInterface _inter) {
    if (out_ == null) {
      analyze_.addFatalError(DodicoLib.getS("Le flux de sortie est nul"));
      return false;
    }
    if (_inter == null) {
      analyze_.addFatalError(DodicoLib.getS("Les donn?es sont nulles"));
      return false;
    }
    if (_inter.getGrid().getEltType() != EfElementType.T6) {
      analyze_.addFatalError(H2dResource.getS("Le maillage doit ?tre de type T6"));
      return false;
    }
    return true;
  }

  private double[] getTimesSteps(final DodicoArrayList _evols, final double _maxTime, final double _minTime) {
    final TDoubleHashSet times = new TDoubleHashSet(100);
    times.add(_maxTime);
    times.add(_minTime);
    // controle basique
    final int nbCurves = _evols.size();
    // on parcourt les courbes et si la
    for (int i = 0; i < nbCurves; i++) {

      final EvolutionReguliere ei = (EvolutionReguliere) _evols.get(i);
      times.addAll(ei.getArrayX());
    }
    final double[] timeStep = times.toArray();
    Arrays.sort(timeStep);
    return timeStep;
  }

  @Override
  protected FortranInterface getFortranInterface() {
    return out_;
  }

  @Override
  protected void internalWrite(final Object _o) {
    if (_o instanceof INPInterface) {
      writeINP((INPInterface) _o);
    } else {
      donneesInvalides(_o);
    }
  }

  /**
   * @return la version
   */
  public FileFormatVersionInterface getVersion() {
    return version_;
  }

  @Override
  public void setFile(final File _f) {
    if (progress_ != null) {
      progress_.setDesc(super.getOperationDescription(_f));
    }
    baseDir_ = _f.getAbsoluteFile().getParentFile().getAbsolutePath();
    // ficName_=DodicoLib.getSansExtension(_f.getName());
    analyze_ = new CtuluAnalyze();
    try {
      out_ = new FortranWriter(new FileWriter(_f));
    } catch (final IOException e) {
      analyze_.manageException(e);
    }
  }

  /**
   * @param _string le separateur de ligne
   */
  public void setLineSep(final String _string) {
    lineSep_ = _string;
  }

  /**
   * @param _o la source a ecrire
   * @return la synthese de l'ecriture.
   */
  public final CtuluIOOperationSynthese write(final INPInterface _o) {
    writeINP(_o);
    return closeOperation(_o);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy