1#ifndef EnKF_1DinverseHeatTransfer_H
2#define EnKF_1DinverseHeatTransfer_H
3#include "simpleControl.H"
10class EnKF_1DinverseHeatTransfer:
public laplacianProblem
13 explicit EnKF_1DinverseHeatTransfer(
int argc,
char* argv[],
int Nseeds_)
15 laplacianProblem(argc, argv)
17 fvMesh& mesh =
_mesh();
18 _simple = autoPtr<simpleControl>
25 simpleControl& simple =
_simple();
27#include "createFvOptions.H"
28 left_ind = mesh.boundaryMesh().findPatchID(
"left");
31 volScalarField& T(
_T());
33 priorSamples = Eigen::MatrixXd::Zero(stateSize,
Nseeds);
34 posteriorSamples = priorSamples;
35 startTime = runTime.startTime().value();
36 deltaTime = runTime.deltaTValue();
37 endTime = runTime.endTime().value();
38 Ntimes = (endTime - startTime) / deltaTime;
39 Info <<
"startTime = " << startTime << endl;
40 Info <<
"endTime = " << endTime << endl;
41 Info <<
"deltaTime = " << deltaTime << endl;
42 Info <<
"Ntimes = " << Ntimes << endl;
44 probe_mean.resize(
Nprobes, Ntimes);
45 probe_true = probe_mean;
46 probe_MaxConfidence = probe_mean;
47 probe_minConfidence = probe_mean;
52 autoPtr<fv::options> _fvOptions;
61 Eigen::MatrixXd measurements;
73 std::shared_ptr<muq::Modeling::Gaussian> priorDensity;
74 std::shared_ptr<muq::Modeling::Gaussian> modelErrorDensity;
75 std::shared_ptr<muq::Modeling::Gaussian> measNoiseDensity;
78 Eigen::MatrixXd priorSamples;
79 Eigen::MatrixXd posteriorSamples;
92 Eigen::MatrixXd probe_true;
93 Eigen::MatrixXd probe_mean;
94 Eigen::MatrixXd probe_MaxConfidence;
95 Eigen::MatrixXd probe_minConfidence;
97 int samplingTimeI = 0;
106 scalar time = runTime.value();
107 double BC = time * 5 + 2;
128 fvMesh& mesh =
_mesh();
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])];
153 Eigen::MatrixXd
solve(volScalarField& T, word outputFolder,
154 word outputFieldName,
bool reconstruction = 0)
156 Eigen::MatrixXd obsMat;
157 fvMesh& mesh =
_mesh();
159 simpleControl& simple =
_simple();
160 fv::options& fvOptions(_fvOptions());
161 dimensionedScalar diffusivity(
"diffusivity", dimensionSet(0, 2, -1, 0, 0, 0, 0),
163 Info <<
"Thermal diffusivity = " << diffusivity <<
" m2/s" << endl;
166 while (runTime.loop())
168 scalar time = runTime.value();
182 while (simple.correctNonOrthogonal())
186 fvm::ddt(T) - fvm::laplacian(diffusivity, T)
188 fvOptions.constrain(TEqn);
190 fvOptions.correct(T);
196 forAll(T.internalField(), cellI)
198 T.ref()[cellI] += modelErrorDensity->Sample()(cellI);
212 Info <<
"Sampling at time = " << runTime.timeName() << nl << endl;
213 obsMat.conservativeResize(
observe(T).size(), obsMat.cols() + 1);
214 obsMat.col(sampleI) =
observe(T);
238 Info <<
"\n****************************************\n" << endl;
239 Info <<
"\nPerforming true solution\n" << endl;
240 word outputFolder =
"./ITHACAoutput/direct/";
242 volScalarField& T(
_T());
244 measurements =
solve(T, outputFolder,
"Tdirect");
247 std::cout <<
"Number of samples in time = " << measurements.cols() << std::endl;
248 std::cout <<
"Number of sample in space = " << measurements.rows() << std::endl;
250 Info <<
"\nEND true solution\n" << endl;
251 Info <<
"\n****************************************\n" << endl;
261 std::vector<Eigen::MatrixXd> observationTensor;
262 word outputFolder =
"ITHACAoutput/reconstuction";
263 Tmean.resize(Ntimes);
264 Info <<
"\n****************************************\n" << endl;
265 Info <<
"\nStarting reconstruction\n" << endl;
266 int samplesCounter = 0;
268 PtrList<volScalarField> Ttrue;
270 "ITHACAoutput/direct/");
272 for (
int timeI = 0; timeI < Ntimes; timeI++)
274 double initialTime = timeI * deltaTime + startTime;
275 Info <<
"\n\nTime " << initialTime + deltaTime << endl;
276 Eigen::MatrixXd forecastOutput =
forecastStep(initialTime, timeI,
277 initialTime + deltaTime);
279 if (forecastOutput.cols() > 0)
283 observationTensor.push_back(forecastOutput);
285 Eigen::VectorXd meas = measurements.col(samplesCounter - 1);
287 posteriorSamples = ITHACAmuq::muq2ithaca::EnsembleKalmanFilter(
Tensemble, meas,
288 Eigen::MatrixXd::Identity(meas.size(), meas.size()) * meas_cov, forecastOutput);
290 for (
int i = 0; i <
Nseeds; i++)
293 volScalarField& T =
_T();
294 Eigen::VectorXd internalField = posteriorSamples.col(i);
296 Tensemble.Foam::PtrList<volScalarField>::set(i, T.clone());
301 Info <<
"debug : NOT a sampling step" << endl;
310 outputFolder,
"Tmean");
312 std::to_string(initialTime + deltaTime),
313 outputFolder,
"Ttrue");
317 for (
int i = 0; i <
Nseeds; i++)
322 probe_mean.col(timeI) = ensambleProbe.rowwise().mean();
323 probe_MaxConfidence.col(timeI) = ITHACAmuq::muq2ithaca::quantile(ensambleProbe,
325 probe_minConfidence.col(timeI) = ITHACAmuq::muq2ithaca::quantile(ensambleProbe,
334 Info <<
"\n****************************************\n" << endl;
342 word outputFolder =
"ITHACAoutput/forwardSamples";
343 bool reconstructionFlag = 1;
344 Eigen::MatrixXd observationMat;
347 for (
int i = 0; i <
Nseeds; i++)
349 word fieldName =
"Tsample" + std::to_string(i);
350 volScalarField T(
_T());
352 if (startIndex_ == 0)
356 Eigen::VectorXd internalField = priorSamples.col(i);
366 if (observationMat.cols() == 0)
368 observationMat =
solve(T, outputFolder, fieldName, reconstructionFlag);
372 observationMat.conservativeResize(observationMat.rows(),
373 observationMat.cols() + 1);
374 Eigen::MatrixXd observationForCheck =
solve(T, outputFolder, fieldName,
376 M_Assert(observationForCheck.cols() == 1,
377 "The forecast step passed trough more than a sampling step");
378 observationMat.col(i) = observationForCheck;
384 return observationMat;
388 void assignIF(volScalarField& field_, Eigen::VectorXd internalField_)
390 for (
int i = 0; i < internalField_.size(); i++)
392 field_.ref()[i] = internalField_(i);
397 Eigen::VectorXd
sampleField(volScalarField field_, Foam::vector probeLocation_)
399 Foam::fvMesh& mesh =
_mesh();
400 Eigen::VectorXd output(1);
401 output(0) = field_[mesh.findCell(probeLocation_)];
409 instantList Times = runTime.times();
410 runTime.setTime(Times[1], 0);
413 Foam::fvMesh& mesh =
_mesh();
414 _simple = autoPtr<simpleControl>
421 _T = autoPtr<volScalarField>
442 instantList Times = runTime.times();
443 runTime.setTime(startTime_, startIndex_);
444 runTime.setEndTime(endTime_);
446 Foam::fvMesh& mesh =
_mesh();
447 _simple = autoPtr<simpleControl>
459 volScalarField& T(
_T());
460 int stateSize = T.size();
461 Eigen::VectorXd prior_mu = Eigen::MatrixXd::Ones(stateSize, 1) * mean;
462 Eigen::MatrixXd prior_cov = Eigen::MatrixXd::Identity(stateSize,
464 priorDensity = std::make_shared<muq::Modeling::Gaussian>(prior_mu, prior_cov);
470 for (
int i = 0; i <
Nseeds; i++)
472 priorSamples.col(i) = priorDensity->Sample();
475 posteriorSamples = priorSamples;
481 volScalarField& T(
_T());
482 int stateSize = T.size();
483 Eigen::VectorXd modelError_mu = Eigen::MatrixXd::Ones(stateSize, 1) * mean;
484 Eigen::MatrixXd modelError_cov = Eigen::MatrixXd::Identity(stateSize,
486 modelErrorDensity = std::make_shared<muq::Modeling::Gaussian>(modelError_mu,
494 int obsSize = measurements.rows();
495 M_Assert(obsSize > 0,
"Read measurements before setting up the noise");
496 Eigen::VectorXd measNoise_mu = Eigen::MatrixXd::Ones(obsSize, 1) * mean;
497 Eigen::MatrixXd measNoise_cov = Eigen::MatrixXd::Identity(obsSize,
499 measNoiseDensity = std::make_shared<muq::Modeling::Gaussian>(measNoise_mu,
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.
void priorSetup(double mean, double cov)
Setup of the prior distribution.
int Nseeds
Number of seeds in the ensemble.
Eigen::VectorXd timeVector
Timesteps vector.
void assignIF(volScalarField &field_, Eigen::VectorXd internalField_)
Assign internalField given an Eigen Vector.
autoPtr< simpleControl > _simple
[tutorial02]
void measNoiseSetup(double mean, double cov)
Setup of the measurement noise distribution.
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.
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.
PtrList< volScalarField > Tensemble
Ensemble.
void restart()
Restart before a now solution.
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.
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.
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.