è¿äºãé
ããªã£ãŠããŸãç³ãèš³ãããŸããã§ããïŒ
é·ãæé¢ã«ãªããŸããïŒããå°ããååããŠããã ãããšå¹žãã§ãïŒ
æ¢åã®timeVaryingMappedFixedValueã©ã€ãã©ãªããå¢çé¢ã®ãããã³ã°éšåãåãå»ããããšèããŠããŸãïŒ
ãããæ°ãã«timeVaryingFixedValueãšããŸãïŒ
å©èšããã ããäžèšã®å
容ãåãå»ã£ãŠã¿ãŸããïŒ
ãå
é ã®ããŒã¿ç¹ããæãé ãç¹ãšå
é ç¹ãšãéãçŽç·ã軞ãšããŠÂ
ãã®è»žããæãé ããµã³ãã«ç¹ã§å®çŸ©ãããå¹³é¢åº§æšã«ãµã³ãã«ç¹Â
ããããã³ã°ããŠïŒæ¬¡å
ããããŒåå²ã§äžè§åœ¢ããããäœæããŠããŸããã
ãããïŒã³ã³ãã€ã«ãšã©ãŒã¯åºãªããã®ã®ããã°ã©ã å®è¡æã«ä»¥äžã®ãšã©ãŒãåºãŸãïŒ
laplacianFoam2_11ãšããã®ã¯å®è¡ãœã«ãã§ãïŒ
ããããã©ã€ãã©ãªã®æ¹è¯ãäžé©åã ãšæãããã®ã§ããïŒããããã©ãããŠãããããããŸããïŒ
ãšã©ãŒã®äžã«ããã°ã©ã timeVaryingFixedValueFvPatchField.CãèŒããŸããã®ã§ïŒ
äœãåé¡ç¹ãæããŠããã ãããšéåžžã«ãããããã§ãïŒ
#0 Â Foam::error::printStack(Foam::Ostream&) in "/home/mou/OpenFOAM/OpenFOAM-2.1.x/platforms/linux64Gcc44DPOpt/lib/libOpenFOAM.so"
#1 Â Foam::sigSegv::sigHandler(int) in "/home/mou/OpenFOAM/OpenFOAM-2.1.x/platforms/linux64Gcc44DPOpt/lib/libOpenFOAM.so"
#2 Â __restore_rt at sigaction.c:0
#3 Â Foam::tmp<Foam::Field<Foam::typeOfSum<double, double>::type> > Foam::operator-<double, double>(Foam::UList<double> const&, Foam::tmp<Foam::Field<double> > const&) in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#4 Â Foam::fvPatchField<double>::snGrad() const in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#5 Â Foam::fv::gaussGrad<double>::correctBoundaryConditions(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>&) in "/home/mou/OpenFOAM/OpenFOAM-2.1.x/platforms/linux64Gcc44DPOpt/lib/libfiniteVolume.so"
#6 Â Foam::fv::leastSquaresGrad<double>::calcGrad(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::word const&) const in "/home/mou/OpenFOAM/OpenFOAM-2.1.x/platforms/linux64Gcc44DPOpt/lib/libfiniteVolume.so"
#7 Â Foam::fv::gradScheme<double>::grad(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::word const&) const in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#8 Â Foam::tmp<Foam::GeometricField<Foam::outerProduct<Foam::Vector<double>, double>::type, Foam::fvPatchField, Foam::volMesh> > Foam::fvc::grad<double>(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&, Foam::word const&) in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#9 Â Foam::tmp<Foam::GeometricField<Foam::outerProduct<Foam::Vector<double>, double>::type, Foam::fvPatchField, Foam::volMesh> > Foam::fvc::grad<double>(Foam::GeometricField<double, Foam::fvPatchField, Foam::volMesh> const&) in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#10 Â main in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
#11 Â __libc_start_main in "/lib64/libc.so.6"
#12 Â Foam::regIOobject::writeObject(Foam::IOstream::streamFormat, Foam::IOstream::versionNumber, Foam::IOstream::compressionType) const in "/home/mou/OpenFOAM/mou-2.1.x/platforms/linux64Gcc44DPOpt/bin/laplacianFoam2_11"
ã»ã°ã¡ã³ããŒã·ã§ã³éåã§ã
src/finiteVolume/fields/fvPatchFields/derived/timeVaryingFixedValueFvPatchField.C
/*---------------------------------------------------------------------------*\
 =========         |
 \\    /  F ield     | OpenFOAM: The Open Source CFD Toolbox
  \\   /  O peration   |
  \\  /   A nd      | Copyright (C) 2011 OpenFOAM Foundation
   \\/   M anipulation  |
-------------------------------------------------------------------------------
License
  This file is part of OpenFOAM.
  OpenFOAM is free software: you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  You should have received a copy of the GNU General Public License
\*---------------------------------------------------------------------------*/
#include "timeVaryingFixedValueFvPatchField.H"
#include "Time.H"
#include "triSurfaceTools.H"
#include "triSurface.H"
#include "vector2D.H"
#include "OFstream.H"
#include "AverageIOField2.H"
#include "Random.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
template<class Type>
timeVaryingFixedValueFvPatchField<Type>::
timeVaryingFixedValueFvPatchField
(
  const fvPatch& p,
  const DimensionedField<Type, volMesh>& iF
)
:
  fixedValueFvPatchField<Type>(p, iF),
  fieldTableName_(iF.name()),
  setAverage_(false),
  perturb_(0),
  referenceCS_(NULL),
  nearestVertex_(0),
  nearestVertexWeight_(0),
  sampleTimes_(0),
  startSampleTime_(-1),
  startSampledValues_(0),
  startAverage_(pTraits<Type>::zero),
  endSampleTime_(-1),
  endSampledValues_(0),
  endAverage_(pTraits<Type>::zero)
{}
template<class Type>
timeVaryingFixedValueFvPatchField<Type>::
timeVaryingFixedValueFvPatchField
(
  const timeVaryingFixedValueFvPatchField<Type>& ptf,
  const fvPatch& p,
  const DimensionedField<Type, volMesh>& iF,
  const fvPatchFieldMapper& mapper
)
:
  fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
  fieldTableName_(ptf.fieldTableName_),
  setAverage_(ptf.setAverage_),
  perturb_(ptf.perturb_),
  referenceCS_(NULL),
  nearestVertex_(0),
  nearestVertexWeight_(0),
  sampleTimes_(0),
  startSampleTime_(-1),
  startSampledValues_(0),
  startAverage_(pTraits<Type>::zero),
  endSampleTime_(-1),
  endSampledValues_(0),
  endAverage_(pTraits<Type>::zero)
{}
template<class Type>
timeVaryingFixedValueFvPatchField<Type>::
timeVaryingFixedValueFvPatchField
(
  const fvPatch& p,
  const DimensionedField<Type, volMesh>& iF,
  const dictionary& dict
)
:
  fixedValueFvPatchField<Type>(p, iF),
  fieldTableName_(iF.name()),
  setAverage_(readBool(dict.lookup("setAverage"))),
  perturb_(dict.lookupOrDefault("perturb", 1E-5)),
  referenceCS_(NULL),
  nearestVertex_(0),
  nearestVertexWeight_(0),
  sampleTimes_(0),
  startSampleTime_(-1),
  startSampledValues_(0),
  startAverage_(pTraits<Type>::zero),
  endSampleTime_(-1),
  endSampledValues_(0),
  endAverage_(pTraits<Type>::zero)
{
  dict.readIfPresent("fieldTableName", fieldTableName_);
  if (dict.found("value"))
  {
    fvPatchField<Type>::operator==(Field<Type>("value", dict, p.size()));
  }
  else
  {
    updateCoeffs();
  }
}
template<class Type>
timeVaryingFixedValueFvPatchField<Type>::
timeVaryingFixedValueFvPatchField
(
  const timeVaryingFixedValueFvPatchField<Type>& ptf
)
:
  fixedValueFvPatchField<Type>(ptf),
  fieldTableName_(ptf.fieldTableName_),
  setAverage_(ptf.setAverage_),
  perturb_(ptf.perturb_),
  referenceCS_(ptf.referenceCS_),
  nearestVertex_(ptf.nearestVertex_),
  nearestVertexWeight_(ptf.nearestVertexWeight_),
  sampleTimes_(ptf.sampleTimes_),
  startSampleTime_(ptf.startSampleTime_),
  startSampledValues_(ptf.startSampledValues_),
  startAverage_(ptf.startAverage_),
  endSampleTime_(ptf.endSampleTime_),
  endSampledValues_(ptf.endSampledValues_),
  endAverage_(ptf.endAverage_)
{}
template<class Type>
timeVaryingFixedValueFvPatchField<Type>::
timeVaryingFixedValueFvPatchField
(
  const timeVaryingFixedValueFvPatchField<Type>& ptf,
  const DimensionedField<Type, volMesh>& iF
)
:
  fixedValueFvPatchField<Type>(ptf, iF),
  fieldTableName_(ptf.fieldTableName_),
  setAverage_(ptf.setAverage_),
  perturb_(ptf.perturb_),
  referenceCS_(ptf.referenceCS_),
  nearestVertex_(ptf.nearestVertex_),
  nearestVertexWeight_(ptf.nearestVertexWeight_),
  sampleTimes_(ptf.sampleTimes_),
  startSampleTime_(ptf.startSampleTime_),
  startSampledValues_(ptf.startSampledValues_),
  startAverage_(ptf.startAverage_),
  endSampleTime_(ptf.endSampleTime_),
  endSampledValues_(ptf.endSampledValues_),
  endAverage_(ptf.endAverage_)
{}
// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::autoMap
(
  const fvPatchFieldMapper& m
)
{
  fixedValueFvPatchField<Type>::autoMap(m);
  if (startSampledValues_.size())
  {
    startSampledValues_.autoMap(m);
    endSampledValues_.autoMap(m);
  }
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::rmap
(
  const fvPatchField<Type>& ptf,
  const labelList& addr
)
{
  fixedValueFvPatchField<Type>::rmap(ptf, addr);
  const timeVaryingFixedValueFvPatchField<Type>& tiptf =
    refCast<const timeVaryingFixedValueFvPatchField<Type> >(ptf);
  startSampledValues_.rmap(tiptf.startSampledValues_, addr);
  endSampledValues_.rmap(tiptf.endSampledValues_, addr);
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::readSamplePoints()
{
  // Read the sample points
  pointIOField samplePoints
  (
    IOobject
    (
      "points",
      this->db().time().constant(),
      "boundaryData"/this->patch().name(),
      this->db(),
      IOobject::MUST_READ,
      IOobject::AUTO_WRITE,
      false
    )
  );
  const fileName samplePointsFile = samplePoints.filePath();
  if (debug)
  {
    Info<< "timeVaryingFixedValueFvPatchField :"
      << " Read " << samplePoints.size() << " sample points from "
      << samplePointsFile << endl;
  }
  // Read the times for which data is available
  const fileName samplePointsDir = samplePointsFile.path();
  sampleTimes_ = Time::findTimes(samplePointsDir);
  if (debug)
  {
    Info<< "timeVaryingFixedValueFvPatchField : In directory "
      << samplePointsDir << " found times " << timeNames(sampleTimes_)
      << endl;
  }
}
template<class Type>
wordList timeVaryingFixedValueFvPatchField<Type>::timeNames
(
  const instantList& times
)
{
  wordList names(times.size());
  forAll(times, i)
  {
    names[i] = times[i].name();
  }
  return names;
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::findTime
(
  const fileName& instance,
  const fileName& local,
  const scalar timeVal,
  label& lo,
  label& hi
) const
{
  lo = startSampleTime_;
  hi = -1;
  for (label i = startSampleTime_+1; i < sampleTimes_.size(); i++)
  {
    if (sampleTimes_[i].value() > timeVal)
    {
      break;
    }
    else
    {
      lo = i;
    }
  }
  if (lo == -1)
  {
    FatalErrorIn("findTime")
      << "Cannot find starting sampling values for current time "
      << timeVal << nl
      << "Have sampling values for times "
      << timeNames(sampleTimes_) << nl
      << "In directory "
      <<  this->db().time().constant()/"boundaryData"/this->patch().name()
      << "\n   on patch " << this->patch().name()
      << " of field " << fieldTableName_
      << exit(FatalError);
  }
  if (lo < sampleTimes_.size()-1)
  {
    hi = lo+1;
  }
  if (debug)
  {
    if (hi == -1)
    {
      Pout<< "findTime : Found time " << timeVal << " after"
        << " index:" << lo << " time:" << sampleTimes_[lo].value()
        << endl;
    }
    else
    {
      Pout<< "findTime : Found time " << timeVal << " inbetween"
        << " index:" << lo << " time:" << sampleTimes_[lo].value()
        << " and index:" << hi << " time:" << sampleTimes_[hi].value()
        << endl;
    }
  }
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::checkTable()
{
  // Initialise
  if (startSampleTime_ == -1 && endSampleTime_ == -1)
  {
    readSamplePoints();
  }
  // Find current time in sampleTimes
  label lo = -1;
  label hi = -1;
  findTime
  (
    this->db().time().constant(),
    "boundaryData"/this->patch().name(),
    this->db().time().value(),
    lo,
    hi
  );
  // Update sampled data fields.
  if (lo != startSampleTime_)
  {
    startSampleTime_ = lo;
    if (startSampleTime_ == endSampleTime_)
    {
      // No need to reread since are end values
      if (debug)
      {
        Pout<< "checkTable : Setting startValues to (already read) "
          <<  "boundaryData"
            /this->patch().name()
            /sampleTimes_[startSampleTime_].name()
          << endl;
      }
      startSampledValues_ = endSampledValues_;
      startAverage_ = endAverage_;
    }
    else
    {
      if (debug)
      {
        Pout<< "checkTable : Reading startValues from "
          <<  "boundaryData"
            /this->patch().name()
            /sampleTimes_[lo].name()
          << endl;
      }
      // Reread values and interpolate
      AverageIOField2<Type> vals
      (
        IOobject
        (
          fieldTableName_,
          this->db().time().constant(),
          "boundaryData"
          /this->patch().name()
          /sampleTimes_[startSampleTime_].name(),
          this->db(),
          IOobject::MUST_READ,
          IOobject::AUTO_WRITE,
          false
        )
      );
      startAverage_ = vals.average();
      startSampledValues_ = interpolate(vals);
    }
  }
  if (hi != endSampleTime_)
  {
    endSampleTime_ = hi;
    if (endSampleTime_ == -1)
    {
      // endTime no longer valid. Might as well clear endValues.
      if (debug)
      {
        Pout<< "checkTable : Clearing endValues" << endl;
      }
      endSampledValues_.clear();
    }
    else
    {
      if (debug)
      {
        Pout<< "checkTable : Reading endValues from "
          <<  "boundaryData"
            /this->patch().name()
            /sampleTimes_[endSampleTime_].name()
          << endl;
      }
      // Reread values and interpolate
      AverageIOField2<Type> vals
      (
        IOobject
        (
          fieldTableName_,
          this->db().time().constant(),
          "boundaryData"
          /this->patch().name()
          /sampleTimes_[endSampleTime_].name(),
          this->db(),
          IOobject::MUST_READ,
          IOobject::AUTO_WRITE,
          false
        )
      );
      endAverage_ = vals.average();
      endSampledValues_ = interpolate(vals);
    }
  }
}
template<class Type>
tmp<Field<Type> > timeVaryingFixedValueFvPatchField<Type>::interpolate
(
  const Field<Type>& sourceFld
) const
{
  tmp<Field<Type> > tfld(new Field<Type>(nearestVertex_.size()));
  Field<Type>& fld = tfld();
  forAll(fld, i)
  {
    const FixedList<label, 3>& verts = nearestVertex_[i];
    const FixedList<scalar, 3>& w = nearestVertexWeight_[i];
    if (verts[2] == -1)
    {
      if (verts[1] == -1)
      {
        // Use vertex0 only
        fld[i] = sourceFld[verts[0]];
      }
      else
      {
        // Use vertex 0,1
        fld[i] =
          w[0]*sourceFld[verts[0]]
         + w[1]*sourceFld[verts[1]];
      }
    }
    else
    {
      fld[i] =
        w[0]*sourceFld[verts[0]]
       + w[1]*sourceFld[verts[1]]
       + w[2]*sourceFld[verts[2]];
    }
  }
  return tfld;
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::updateCoeffs()
{
  if (this->updated())
  {
    return;
  }
  checkTable();
  // Interpolate between the sampled data
  Type wantedAverage;
  if (endSampleTime_ == -1)
  {
    // only start value
    if (debug)
    {
      Pout<< "updateCoeffs : Sampled, non-interpolated values"
        << " from start time:"
        << sampleTimes_[startSampleTime_].name() << nl;
    }
    this->operator==(startSampledValues_);
    wantedAverage = startAverage_;
  }
  else
  {
    scalar start = sampleTimes_[startSampleTime_].value();
    scalar end = sampleTimes_[endSampleTime_].value();
    scalar s = (this->db().time().value()-start)/(end-start);
    if (debug)
    {
      Pout<< "updateCoeffs : Sampled, interpolated values"
        << " between start time:"
        << sampleTimes_[startSampleTime_].name()
        << " and end time:" << sampleTimes_[endSampleTime_].name()
        << " with weight:" << s << endl;
    }
    this->operator==((1-s)*startSampledValues_ + s*endSampledValues_);
    wantedAverage = (1-s)*startAverage_ + s*endAverage_;
  }
  // Enforce average. Either by scaling (if scaling factor > 0.5) or by
  // offsetting.
  if (setAverage_)
  {
    const Field<Type>& fld = *this;
    Type averagePsi =
      gSum(this->patch().magSf()*fld)
      /gSum(this->patch().magSf());
    if (debug)
    {
      Pout<< "updateCoeffs :"
        << " actual average:" << averagePsi
        << " wanted average:" << wantedAverage
        << endl;
    }
    if (mag(averagePsi) < VSMALL)
    {
      // Field too small to scale. Offset instead.
      const Type offset = wantedAverage - averagePsi;
      if (debug)
      {
        Pout<< "updateCoeffs :"
          << " offsetting with:" << offset << endl;
      }
      this->operator==(fld+offset);
    }
    else
    {
      const scalar scale = mag(wantedAverage)/mag(averagePsi);
      if (debug)
      {
        Pout<< "updateCoeffs :"
          << " scaling with:" << scale << endl;
      }
      this->operator==(scale*fld);
    }
  }
  if (debug)
  {
    Pout<< "updateCoeffs : set fixedValue to min:" << gMin(*this)
      << " max:" << gMax(*this) << endl;
  }
  fixedValueFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void timeVaryingFixedValueFvPatchField<Type>::write(Ostream& os) const
{
  fvPatchField<Type>::write(os);
  os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
  os.writeKeyword("peturb") << perturb_ << token::END_STATEMENT << nl;
  if (fieldTableName_ != this->dimensionedInternalField().name())
  {
    os.writeKeyword("fieldTableName") << fieldTableName_
      << token::END_STATEMENT << nl;
  }
  this->writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //
2012幎2æ21æ¥ç«ææ¥6æ54å49ç§ UTC+9 ohbuchi: