ReFRACtor
fd_forward_model.cc
Go to the documentation of this file.
1 #include "fd_forward_model.h"
2 using namespace FullPhysics;
3 using namespace blitz;
4 
5 #include "logger.h"
6 
7 //-----------------------------------------------------------------------
9 //-----------------------------------------------------------------------
10 
13  const blitz::Array<double, 1>& Perturbation)
14  : real_fm(Real_forward_model), statev(Sv), perturb(Perturbation)
15 {
16 }
17 
18 // See base class for description.
19 
20 Spectrum FdForwardModel::radiance(int Spec_index, bool Skip_jacobian) const
21 {
22  if(Skip_jacobian)
23  return real_fm->radiance(Spec_index, Skip_jacobian);
24 
25  // Save initial state of statevector to set back at end of jacobian looping
26  Array<double, 1> initial_sv( statev->state() );
27 
28  // Retrieve unperturbed radiance value
29  Logger::info() << "Finite Difference FM: Unperturbed radiances\n";
30  Spectrum rad(real_fm->radiance(Spec_index, true));
31 
32  // Set up result ArrayAD class
33  ArrayAd<double, 1> res(rad.spectral_range().data().rows(),
34  statev->state_with_derivative().number_variable());
35  res.value() = rad.spectral_range().data();
36 
37  // Make sure statevector size is same as perturbation array
38  if( initial_sv.extent(firstDim) != perturb.extent(firstDim) ) {
39  Exception err;
40  err << "Statevector size does not match size of perturbation array, can not do FD jacobian calculations";
41  throw(err);
42  }
43 
44  // Loop over statevector perturbing each item in turn, saving value into jacobian array
45  Array<double, 1> current_sv(initial_sv.extent(firstDim));
46  for( int sv_idx = 0; sv_idx < initial_sv.extent(firstDim); sv_idx++) {
47  Logger::info() << "Finite Difference FM: Perturbation of state vector element #" << sv_idx+1 << "\n";
48  if( perturb(sv_idx) > 0.0 ) {
49  // Copy original and add perturbation for current element
50  current_sv = initial_sv;
51  current_sv(sv_idx) += perturb(sv_idx);
52 
53  // Update statevector so calculations are done w/ perturbed values
54  statev->update_state(current_sv);
55 
56  // Calculate FD jacobian value
57  res.jacobian()(Range::all(), sv_idx) =
58  (real_fm->radiance(Spec_index, true).spectral_range().data() -
59  rad.spectral_range().data()) / perturb(sv_idx);;
60 
61  } else {
62  // Set to all zeros if perturbation is 0.0 since
63  // the perturbation would have no effect
64  res.jacobian()(Range::all(), sv_idx) = 0.0;
65  }
66  }
67 
68  // Set statevector object back to initial state
69  statev->update_state(initial_sv);
70 
71  return Spectrum(rad.spectral_domain(),
72  SpectralRange(res, rad.spectral_range().units()));
73 }
static LogHelper info()
Definition: logger.h:109
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
Apply value function to a blitz array.
const blitz::Array< T, D > & value() const
Definition: array_ad.h:306
This is a full spectrum, which contains a SpectralRange and SpectralDomain.
Definition: spectrum.h:18
virtual Spectrum radiance(int Spec_index, bool Skip_jacobian=false) const
Spectrum for the given spectral band.
We have a number of different spectrums that appear in different parts of the code.
FdForwardModel(const boost::shared_ptr< ForwardModel > &Real_Forward_model, const boost::shared_ptr< StateVector > &Sv, const blitz::Array< double, 1 > &Perturbation)
Constructor.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
This gets the perturbation to use with a finite difference Jacobian.
Definition: perturbation.h:10
const Unit rad("rad", 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:08