1#ifndef EnKF_1DinverseHeatTransfer_H
2#define EnKF_1DinverseHeatTransfer_H
3#include "simpleControl.H"
18 _simple = autoPtr<simpleControl>
31 volScalarField&
T(
_T());
39 Info <<
"startTime = " <<
startTime << endl;
40 Info <<
"endTime = " <<
endTime << endl;
41 Info <<
"deltaTime = " <<
deltaTime << endl;
42 Info <<
"Ntimes = " <<
Ntimes << endl;
107 double BC = time * 5 + 2;
130 IOdictionary measurementsDict
141 List<vector> measurementPoints(measurementsDict.lookup(
"positions"));
142 Eigen::VectorXd measures(measurementPoints.size());
143 forAll(measurementPoints, pntI)
147 measures(pntI) = field[
mesh.findCell(measurementPoints[pntI])];
154 Eigen::MatrixXd
solve(volScalarField&
T, word outputFolder,
155 word outputFieldName,
bool reconstruction = 0)
157 Eigen::MatrixXd obsMat;
162 dimensionedScalar diffusivity(
"diffusivity", dimensionSet(0, 2, -1, 0, 0, 0, 0),
164 Info <<
"Thermal diffusivity = " << diffusivity <<
" m2/s" << endl;
183 while (
simple.correctNonOrthogonal())
187 fvm::ddt(
T) - fvm::laplacian(diffusivity,
T)
197 forAll(
T.internalField(), cellI)
213 Info <<
"Sampling at time = " <<
runTime.timeName() << nl << endl;
214 obsMat.conservativeResize(
observe(
T).size(), obsMat.cols() + 1);
239 Info <<
"\n****************************************\n" << endl;
240 Info <<
"\nPerforming true solution\n" << endl;
241 word outputFolder =
"./ITHACAoutput/direct/";
243 volScalarField&
T(
_T());
248 std::cout <<
"Number of samples in time = " <<
measurements.cols() << std::endl;
249 std::cout <<
"Number of sample in space = " <<
measurements.rows() << std::endl;
251 Info <<
"\nEND true solution\n" << endl;
252 Info <<
"\n****************************************\n" << endl;
262 std::vector<Eigen::MatrixXd> observationTensor;
263 word outputFolder =
"ITHACAoutput/reconstuction";
265 Info <<
"\n****************************************\n" << endl;
266 Info <<
"\nStarting reconstruction\n" << endl;
267 int samplesCounter = 0;
269 PtrList<volScalarField> Ttrue;
271 "ITHACAoutput/direct/");
273 for (
int timeI = 0; timeI <
Ntimes; timeI++)
276 Info <<
"\n\nTime " << initialTime +
deltaTime << endl;
277 Eigen::MatrixXd forecastOutput =
forecastStep(initialTime, timeI,
280 if (forecastOutput.cols() > 0)
284 observationTensor.push_back(forecastOutput);
286 Eigen::VectorXd meas =
measurements.col(samplesCounter - 1);
289 Eigen::MatrixXd::Identity(meas.size(), meas.size()) *
meas_cov, forecastOutput);
294 volScalarField&
T =
_T();
297 Tensemble.Foam::PtrList<volScalarField>::set(
i,
T.clone());
302 Info <<
"debug : NOT a sampling step" << endl;
311 outputFolder,
"Tmean");
314 outputFolder,
"Ttrue");
323 probe_mean.col(timeI) = ensambleProbe.rowwise().mean();
335 Info <<
"\n****************************************\n" << endl;
343 word outputFolder =
"ITHACAoutput/forwardSamples";
344 bool reconstructionFlag = 1;
345 Eigen::MatrixXd observationMat;
350 word fieldName =
"Tsample" + std::to_string(
i);
351 volScalarField
T(
_T());
353 if (startIndex_ == 0)
367 if (observationMat.cols() == 0)
369 observationMat =
solve(
T, outputFolder, fieldName, reconstructionFlag);
373 observationMat.conservativeResize(observationMat.rows(),
374 observationMat.cols() + 1);
375 Eigen::MatrixXd observationForCheck =
solve(
T, outputFolder, fieldName,
377 M_Assert(observationForCheck.cols() == 1,
378 "The forecast step passed trough more than a sampling step");
379 observationMat.col(
i) = observationForCheck;
385 return observationMat;
389 void assignIF(volScalarField& field_, Eigen::VectorXd internalField_)
391 for (
int i = 0;
i < internalField_.size();
i++)
393 field_.ref()[
i] = internalField_(
i);
398 Eigen::VectorXd
sampleField(volScalarField field_, Foam::vector probeLocation_)
401 Eigen::VectorXd output(1);
402 output(0) = field_[
mesh.findCell(probeLocation_)];
410 instantList Times =
runTime.times();
415 _simple = autoPtr<simpleControl>
422 _T = autoPtr<volScalarField>
443 instantList Times =
runTime.times();
444 runTime.setTime(startTime_, startIndex_);
448 _simple = autoPtr<simpleControl>
460 volScalarField&
T(
_T());
462 Eigen::VectorXd prior_mu = Eigen::MatrixXd::Ones(
stateSize, 1) * mean;
463 Eigen::MatrixXd prior_cov = Eigen::MatrixXd::Identity(
stateSize,
465 priorDensity = std::make_shared<muq::Modeling::Gaussian>(prior_mu, prior_cov);
482 volScalarField&
T(
_T());
484 Eigen::VectorXd modelError_mu = Eigen::MatrixXd::Ones(
stateSize, 1) * mean;
485 Eigen::MatrixXd modelError_cov = Eigen::MatrixXd::Identity(
stateSize,
496 M_Assert(obsSize > 0,
"Read measurements before setting up the noise");
497 Eigen::VectorXd measNoise_mu = Eigen::MatrixXd::Ones(obsSize, 1) * mean;
498 Eigen::MatrixXd measNoise_cov = Eigen::MatrixXd::Identity(obsSize,
forAll(example_CG.gList, solutionI)
#define M_Assert(Expr, Msg)
Eigen::VectorXd observe(volScalarField field)
Returns the input field values at the measurement points defined in the measurementsDict.
PtrList< volScalarField > Tmean
Mean field of the ensemble.
label left_ind
Index of the left patch.
void resetRunTime(double startTime_, int startIndex_, double endTime_)
Reset runTime to given values.
Eigen::MatrixXd probe_MaxConfidence
Eigen::MatrixXd measurements
std::shared_ptr< muq::Modeling::Gaussian > priorDensity
std::shared_ptr< muq::Modeling::Gaussian > measNoiseDensity
void priorSetup(double mean, double cov)
Setup of the prior distribution.
int Nseeds
Number of seeds in the ensemble.
Eigen::MatrixXd probe_true
Eigen::VectorXd timeVector
Timesteps vector.
void assignIF(volScalarField &field_, Eigen::VectorXd internalField_)
Assign internalField given an Eigen Vector.
EnKF_1DinverseHeatTransfer(int argc, char *argv[], int Nseeds_)
autoPtr< simpleControl > _simple
[tutorial02]
void measNoiseSetup(double mean, double cov)
Setup of the measurement noise distribution.
std::shared_ptr< muq::Modeling::Gaussian > modelErrorDensity
void modelErrorSetup(double mean, double cov)
Setup of the model error distribution.
double updateBC(bool reconstruction=0)
Updates the boundary conditions according to runTime.
Foam::vector probePosition
Probles position, probes are used only for visualization and postprocessing.
Eigen::MatrixXd priorSamples
void reconstruct()
Reconstruction phase.
int Nprobes
Number of probes.
void resetSamplingCounters()
Set all the sampling counters to 0.
Eigen::MatrixXd forecastStep(double startTime_, int startIndex_, double endTime_)
Forecasting step.
Eigen::MatrixXd probe_mean
autoPtr< fv::options > _fvOptions
PtrList< volScalarField > Tensemble
Ensemble.
void restart()
Restart before a now solution.
Eigen::MatrixXd posteriorSamples
void solveDirect()
Preforming a true solution.
int NtimeStepsBetweenSamps
Number of timesteps between each sampling.
Eigen::MatrixXd solve(volScalarField &T, word outputFolder, word outputFieldName, bool reconstruction=0)
Solve the heat transfer problem.
Eigen::MatrixXd probe_minConfidence
void priorSampling()
Samples the prior density.
Eigen::VectorXd sampleField(volScalarField field_, Foam::vector probeLocation_)
Samples a field in a given point.
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field)
autoPtr< volScalarField > _T
Temperature field.
autoPtr< fvMesh > _mesh
Mesh.
autoPtr< Time > _runTime
Time.
Eigen::MatrixXd EnsembleKalmanFilter(Eigen::MatrixXd prior, Eigen::VectorXd measurements, Eigen::MatrixXd measurementsCov, Eigen::MatrixXd observedState)
Ensemble Kalman Filter.
double quantile(Eigen::VectorXd samps, double p, int method)
Returns quantile for a vector of samples.
void exportSolution(GeometricField< Type, PatchField, GeoMesh > &s, fileName subfolder, fileName folder, word fieldName)
Export a field to file in a certain folder and subfolder.
void exportMatrix(Eigen::Matrix< T, -1, dim > &matrix, word Name, word type, word folder)
Export the reduced matrices in numpy (type=python), matlab (type=matlab) and txt (type=eigen) format ...
void read_fields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, word Name, fileName casename, int first_snap, int n_snap)
Function to read a list of fields from the name of the field and casename.
void assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.
simpleControl simple(mesh)