Skip to content

Commit fa7c893

Browse files
committed
Add interpolator increment apply and adjoint methods and add increment to
state method. Update yaml 3DVar yaml file so 3DVar runs through (but produces nans currently).
1 parent fd34d29 commit fa7c893

File tree

5 files changed

+183
-22
lines changed

5 files changed

+183
-22
lines changed

src/orca-jedi/interpolator/Interpolator.cc

+144
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "orca-jedi/geometry/Geometry.h"
2929
#include "orca-jedi/state/State.h"
30+
#include "orca-jedi/increment/Increment.h"
3031

3132
#include "orca-jedi/interpolator/Interpolator.h"
3233

@@ -177,6 +178,149 @@ template void Interpolator::executeInterpolation<float>(
177178
const std::vector<bool> & mask,
178179
std::vector<double>::iterator& iter) const;
179180

181+
void Interpolator::apply(const oops::Variables& vars, const Increment& inc,
182+
const std::vector<bool> & mask,
183+
std::vector<double>& result) const {
184+
185+
// DJL question can the atlas templates help?
186+
187+
// input is inc output is result
188+
189+
const size_t nvars = vars.size();
190+
191+
for (size_t j=0; j < nvars; ++j) {
192+
if (!inc.variables().has(vars[j])) {
193+
std::stringstream err_stream;
194+
err_stream << "orcamodel::Interpolator::apply varname \" "
195+
<< "\" " << vars[j]
196+
<< " not found in the model increment." << std::endl;
197+
err_stream << " add the variable to the increment variables and "
198+
<< "add a mapping from the geometry to that variable."
199+
<< std::endl;
200+
throw eckit::BadParameter(err_stream.str(), Here());
201+
}
202+
}
203+
204+
const std::vector<size_t> varSizes =
205+
inc.geometry()->variableSizes(vars);
206+
size_t nvals = 0;
207+
for (size_t jvar=0; jvar < nvars; ++jvar) nvals += nlocs_ * varSizes[jvar];
208+
result.resize(nvals);
209+
210+
std::size_t out_idx = 0;
211+
for (size_t jvar=0; jvar < nvars; ++jvar) {
212+
auto gv_varname = vars[jvar].name();
213+
atlas::Field tgt_field = atlasObsFuncSpace_.createField<double>(
214+
atlas::option::name(gv_varname) |
215+
atlas::option::levels(varSizes[jvar]));
216+
interpolator_.execute(inc.incrementFields()[gv_varname], tgt_field);
217+
auto field_view = atlas::array::make_view<double, 2>(tgt_field);
218+
atlas::field::MissingValue mv(inc.incrementFields()[gv_varname]);
219+
bool has_mv = static_cast<bool>(mv);
220+
for (std::size_t klev=0; klev < varSizes[jvar]; ++klev) {
221+
for (std::size_t iloc=0; iloc < nlocs_; iloc++) {
222+
if (has_mv && mv(field_view(iloc, klev))) {
223+
result[out_idx] = util::missingValue<double>();
224+
} else {
225+
result[out_idx] = field_view(iloc, klev);
226+
}
227+
++out_idx;
228+
}
229+
}
230+
}
231+
}
232+
233+
void Interpolator::applyAD(const oops::Variables& vars, Increment& inc,
234+
const std::vector<bool> & mask,
235+
const std::vector<double> & resultin) const
236+
{
237+
238+
// input is resultin output is inc
239+
240+
oops::Log::trace() << "orcamodel::Interpolator::applyAD start "
241+
<< std::endl;
242+
243+
oops::Log::debug() << "DJL ** Interpolator::applyAD this needs checking **" << std::endl;
244+
245+
// ** Not sure what I'm doing yet - Just trying to do the opposite of applyAD
246+
247+
const size_t nvars = vars.size();
248+
249+
for (size_t j=0; j < nvars; ++j) {
250+
if (!inc.variables().has(vars[j])) {
251+
std::stringstream err_stream;
252+
err_stream << "orcamodel::Interpolator::apply varname \" "
253+
<< "\" " << vars[j]
254+
<< " not found in the model increment." << std::endl;
255+
err_stream << " add the variable to the increment variables and "
256+
<< "add a mapping from the geometry to that variable."
257+
<< std::endl;
258+
throw eckit::BadParameter(err_stream.str(), Here());
259+
}
260+
}
261+
262+
const std::vector<size_t> varSizes =
263+
inc.geometry()->variableSizes(vars);
264+
size_t nvals = 0;
265+
266+
// boost::uuids::uuid uuid = boost::uuids::random_generator()();
267+
// std::shared_ptr<const Geometry> geom = inc.geometry();
268+
// writeGenFieldsToFile("applyADpre"+ boost::uuids::to_string(uuid) +".nc", *geom, inc.validTime(), inc.incrementFields());
269+
270+
for (size_t jvar=0; jvar < nvars; ++jvar) nvals += nlocs_ * varSizes[jvar];
271+
// result.resize(nvals);
272+
273+
std::size_t out_idx = 0;
274+
for (size_t jvar=0; jvar < nvars; ++jvar) {
275+
oops::Log::debug() << "DJL ** jvar " << jvar << " " << nvars
276+
<< "varSizes " << varSizes[jvar]
277+
<< std::endl;
278+
auto gv_varname = vars[jvar].name();
279+
// atlas::Field tgt_field = atlasObsFuncSpace_.createField<double>(
280+
// atlas::option::name(gv_varname) |
281+
// atlas::option::levels(varSizes[jvar]));
282+
// atlas::Field incField = inc.incrementFields()[jvar];
283+
284+
auto tgt_field = atlasObsFuncSpace_.createField<double>(
285+
atlas::option::name(gv_varname) |
286+
atlas::option::levels(varSizes[jvar]));
287+
288+
auto field_view = atlas::array::make_view<double, 2>(tgt_field);
289+
// field_view.assign(0.0);
290+
291+
for (std::size_t klev=0; klev < varSizes[jvar]; ++klev) {
292+
for (std::size_t iloc=0; iloc < nlocs_; iloc++) {
293+
// if (has_mv && mv(field_view(iloc, klev))) {
294+
//// result[out_idx] = util::missingValue(result[out_idx]);
295+
// } else {
296+
oops::Log::debug() << "DJL iloc " << iloc << " klev " << klev << " out_idx "
297+
<< out_idx << " resultin[out_idx] " << resultin[out_idx] << std::endl;
298+
field_view(iloc, klev) = resultin[out_idx];
299+
// }
300+
++out_idx;
301+
}
302+
}
303+
304+
305+
// atlas::field::MissingValue mv(inc.incrementFields()[gv_varname]);
306+
// bool has_mv = static_cast<bool>(mv);
307+
interpolator_.execute_adjoint(inc.incrementFields()[gv_varname], tgt_field);
308+
309+
} // jvar
310+
311+
// DJL write to file
312+
313+
// boost::uuids::uuid uuid = boost::uuids::random_generator()();
314+
// std::shared_ptr<const Geometry> geom = inc.geometry();
315+
// std::ostringstream out;
316+
// out << std::setfill('0') << std::setw(6) << uuid;
317+
// writeGenFieldsToFile("applyAD"+ boost::uuids::to_string(uuid) +".nc", *geom, inc.validTime(), inc.incrementFields());
318+
// fileCounter_++;
319+
320+
oops::Log::trace() << "orcamodel::Interpolator::applyAD done "
321+
<< std::endl;
322+
}
323+
180324
void Interpolator::print(std::ostream & os) const {
181325
os << "orcamodel::Interpolator: " << std::endl;
182326
os << " Obs function space " << atlasObsFuncSpace_ << std::endl;

src/orca-jedi/interpolator/Interpolator.h

+3-9
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,10 @@ class Interpolator : public util::Printable,
5858
std::vector<double>& result) const;
5959
void apply(const oops::Variables& vars, const Increment& inc,
6060
const std::vector<bool> & mask,
61-
std::vector<double>& result) const {
62-
throw eckit::NotImplemented("Increment interpolation not implemented",
63-
Here());
64-
}
65-
void applyAD(const oops::Variables& vars, const Increment& inc,
61+
std::vector<double>& result) const;
62+
void applyAD(const oops::Variables& vars, Increment& inc,
6663
const std::vector<bool> & mask,
67-
const std::vector<double> &) const {
68-
throw eckit::NotImplemented("Adjoint interpolation not implemented",
69-
Here());
70-
}
64+
const std::vector<double> &) const;
7165

7266
private:
7367
template<class T> void executeInterpolation(

src/orca-jedi/interpolator/InterpolatorParameters.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class OrcaAtlasInterpolatorParameters : public oops::Parameters {
2222
oops::OptionalParameter<std::string> non_linear{"non_linear", this};
2323
oops::OptionalParameter<double>
2424
max_fraction_elems_to_try{"max_fraction_elems_to_try", this};
25+
oops::OptionalParameter<bool> adjoint{"adjoint", this};
2526
};
2627

2728
class OrcaInterpolatorParameters : public oops::Parameters {

src/orca-jedi/state/State.cc

+28-3
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,35 @@ State & State::operator=(const State & rhs) {
165165
// Interactions with Increments
166166

167167
State & State::operator+=(const Increment & dx) {
168-
std::string err_message =
169-
"orcamodel::State::State::operator+= not implemented";
170-
throw eckit::NotImplemented(err_message, Here());
168+
171169
oops::Log::trace() << "State(ORCA)::add increment starting" << std::endl;
170+
171+
ASSERT(this->validTime() == dx.validTime());
172+
173+
// DJL assumes state and increments have the same fields in the field set
174+
// DJL add something to enforce/check this
175+
176+
auto ghost = atlas::array::make_view<int32_t, 1>(
177+
geom_->mesh().nodes().ghost());
178+
for (int i = 0; i< stateFields_.size();i++)
179+
{
180+
atlas::Field field = stateFields_[i];
181+
atlas::Field fieldi = dx.incrementFields()[i];
182+
183+
std::string fieldName = field.name();
184+
std::string fieldNamei = fieldi.name();
185+
oops::Log::debug() << "orcamodel::Increment::add:: state field name = " << fieldName
186+
<< " increment field name = " << fieldNamei
187+
<< std::endl;
188+
auto field_view = atlas::array::make_view<double, 2>(field);
189+
auto field_viewi = atlas::array::make_view<double, 2>(fieldi);
190+
for (atlas::idx_t j = 0; j < field_view.shape(0); ++j) {
191+
for (atlas::idx_t k = 0; k < field_view.shape(1); ++k) {
192+
if (!ghost(j)) field_view(j, k) += field_viewi(j, k);
193+
}
194+
}
195+
}
196+
172197
oops::Log::trace() << "State(ORCA)::add increment done" << std::endl;
173198
return *this;
174199
}

src/tests/testinput/3dvar_ice_obs.yaml

+7-10
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ cost function:
4444
obsdataout:
4545
engine:
4646
type: H5File
47-
obsfile: testoutput/test_3dvar.nc
47+
obsfile: testoutput/test_3dvar_obsdataout.nc
4848
simulated variables: [ice_area_fraction]
4949
get values:
5050
time interpolation: linear
5151
atlas-interpolator:
5252
type: unstructured-bilinear-lonlat
5353
non_linear: missing-if-all-missing
5454
max_fraction_elems_to_try: 0.0
55-
# adjoint: true
55+
adjoint: true
5656
obs operator:
5757
name: Composite
5858
components:
@@ -91,20 +91,17 @@ variational:
9191
write increment: true
9292
increment:
9393
state component:
94-
datadir: Data
95-
output path: testoutput/increments_ice
94+
output path: testoutput/increments_ice.nc
9695
date: 2021-06-30T00:00:00Z
97-
exp: 3dvar.iter1
98-
type: in
96+
# type: in
9997
final:
10098
diagnostics:
10199
departures: oman
102100
output:
103101
date: 2021-06-30T00:00:00Z
104102
state variables: [ ice_area_fraction ]
105-
nemo field file: testoutput/3dvar_ice
106-
# exp: 3dvar
107-
# steps: ["2021-06-29T12:00:00Z"] # state write not implemented
108-
103+
nemo field file: testoutput/3dvar_ice2.nc
104+
output nemo field file: testoutput/3dvar_ice_analysis.nc
105+
# steps: ["2021-06-29T12:00:00Z"]
109106
#test:
110107
# reference filename: testoutput/test_3dvar_ice_obs.ref

0 commit comments

Comments
 (0)