Canoe
Comprehensive Atmosphere N' Ocean Engine
profile_inversion_posterior.cpp
Go to the documentation of this file.
1 
9 // C/C++ header
10 #include <iostream>
11 #include <memory>
12 #include <sstream>
13 
14 // athena
15 #include <athena/mesh/mesh.hpp>
16 
17 // harp
18 #include <harp/radiation.hpp>
19 
20 // application
21 #include <application/application.hpp>
22 
23 // utils
24 #include <utils/ndarrays.hpp>
25 
26 // inversion
27 #include "profile_inversion.hpp"
28 
30  Real const *par, Real *val,
31  int k) const {
32  Application::Logger app("inversion");
33  int is = pmy_block_->is, ie = pmy_block_->ie;
34  int ks = pmy_block_->ks;
35 
36  int ndim = GetDims();
37  int nvalue = GetValues();
38 
39  // logging
40  app->Log("Calculate LogPosteriorProbability");
41  app->Log("I am walker = " + std::to_string(k - ks));
42 
43  Real **XpSample;
44  NewCArray(XpSample, 1 + NVAPOR, plevel_.size());
45  std::fill(*XpSample, *XpSample + (1 + NVAPOR) * plevel_.size(), 0.);
46 
47  // sample temperature, sample composition #1, sample composition #2, ...
48  // app->Log("parameters = ", par, ndim);
49 
50  int ip = 0;
51  for (auto m : idx_) {
52  XpSample[m][0] = 0.;
53  for (int i = 1; i <= plevel_.size() - 2; ++i)
54  XpSample[m][i] = par[ip * (plevel_.size() - 2) + i - 1];
55  XpSample[m][plevel_.size() - 1] = 0.;
56  ip++;
57  }
58 
59  // update atmosphere based on XpSample
60  UpdateProfiles(phydro, XpSample, k, jl_, ju_);
61 
62  // calculate radiation for updated profiles located at j = jl_ ... ju_
63  for (int j = jl_; j <= ju_; ++j) {
64  app->Log("run RT for model = " + std::to_string(j));
65  prad->CalRadiance(pmy_block_, k, j);
66  }
67 
68  // prior probability
69  Real lnprior = LogPriorProbability(XpSample);
70 
71  // posterior probability
72  Eigen::VectorXd misfit(nvalue);
73 
74  // calculate model result for profile at j = ju_
75  CalculateFitTarget(prad, val, nvalue, k, ju_);
76 
77  Real lnpost = 0.;
78  if (target_.size() > 0) {
79  for (int m = 0; m < nvalue; ++m) misfit(m) = val[m] - target_(m);
80  lnpost = -0.5 * misfit.transpose() * icov_ * misfit;
81  }
82 
83  // posterior probability
84  // Real lnprior = 0., lnpost = 0.;
85  app->Log("log posterir probability = " + std::to_string(lnpost));
86 
87  FreeCArray(XpSample);
88 
89  return lnprior + lnpost;
90 }
Eigen::VectorXd target_
Definition: inversion.hpp:84
int GetDims() const
Definition: inversion.hpp:61
int GetValues() const
Definition: inversion.hpp:62
virtual void CalculateFitTarget(Radiation const *prad, Real *val, int nvalue, int k, int j) const
Definition: inversion.hpp:43
Eigen::MatrixXd icov_
Definition: inversion.hpp:85
MeshBlock const * pmy_block_
pointer to parent MeshBlock
Definition: inversion.hpp:97
virtual Real LogPriorProbability(Real **XpSample) const
std::vector< int > idx_
Real LogPosteriorProbability(Radiation *prad, Hydro *phydro, Real const *par, Real *val, int k) const override
std::vector< Real > plevel_
void UpdateProfiles(Hydro *phydro, Real **XpSample, int k, int jl, int ju) const
void CalRadiance(MeshBlock const *pmb, int k, int j)
Calculate the radiance.
Definition: radiation.cpp:139
void FreeCArray(T **a)
Definition: ndarrays.hpp:13
void NewCArray(T **&a, int n1, int n2)
Definition: ndarrays.hpp:5