static PyObject *MatrixMaker_iceinterp_to_atm(PyMatrixMaker *self, PyObject *args, PyObject *kwds) { PyObject *ret_py = NULL; try { // Get arguments char *ice_sheet_name_py; char *src_py = "ICE"; static char const *keyword_list[] = {"sheetname", "src", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "s|s", const_cast<char **>(keyword_list), &ice_sheet_name_py, &src_py)) { // Throw an exception... PyErr_SetString(PyExc_ValueError, "ice_to_atm() called without a valid string as argument."); return 0; } glint2::MatrixMaker *maker = self->maker.get(); std::string const ice_sheet_name(ice_sheet_name_py); auto src(giss::parse_enum<IceInterp>(src_py)); // Look up the ice sheet IceSheet *sheet = (*maker)[ice_sheet_name]; if (!sheet) { PyErr_SetString(PyExc_ValueError, ("Could not find ice sheet named " + ice_sheet_name).c_str()); return 0; } // Get the ice_to_atm matrix from it giss::MapSparseVector<int,double> area1_m, area1_m_inv; auto ret_c(sheet->iceinterp_to_projatm(area1_m, src)); if (maker->correct_area1) sheet->atm_proj_correct(area1_m, ProjCorrect::PROJ_TO_NATIVE); divide_by(*ret_c, area1_m, area1_m_inv); // Create an output tuple of Numpy arrays ret_py = giss::VectorSparseMatrix_to_py(*ret_c); return ret_py; } catch(...) { if (ret_py) Py_DECREF(ret_py); PyErr_SetString(PyExc_ValueError, "Error in MatrixMaker_ice_to_atm()"); return 0; } }
void GCMCoupler:: regrid_gcm_inputs_onroot( std::vector<giss::VectorSparseVector<int,double>> &gcm_ivals, // Root node only: Already-allocated space to put output values. Members as defined by the CouplingContract GCMCoupler::gcm_inputs unsigned int mask) { // This method is meant to be run only on the GCM root. if (!am_i_root()) return; printf("BEGIN GCMCoupler::regrid_gcm_inputs_onroot\n"); // (ONLY ON GCM ROOT) // =============== Regrid to the grid requested by the GCM // (ONLY ON GCM ROOT) // ----------- Create the MultiMatrix used to regrid to atmosphere (I -> A) MultiMatrix ice2atm; for (auto model = models.begin(); model != models.end(); ++model) { // Get matrix for this single ice model. giss::MapSparseVector<int,double> area1_m; int sheetno = model.key(); // IceSheet::index IceSheet *sheet = (*maker_full)[sheetno]; std::unique_ptr<giss::VectorSparseMatrix> M( sheet->iceinterp_to_projatm(area1_m, IceInterp::ICE)); // Add on correction for projection if (maker_full->correct_area1) { sheet->atm_proj_correct(area1_m, ProjCorrect::PROJ_TO_NATIVE); } // Store it away... ice2atm.add_matrix(std::move(M), area1_m); } // (ONLY ON GCM ROOT) // ------------ Regrid each GCM input from ice grid to whatever grid it needs. for (int var_ix=0; var_ix < gcm_inputs.size_nounit(); ++var_ix) { giss::CoupledField const &cf(gcm_inputs.field(var_ix)); if ((cf.flags & mask) != mask) continue; if ((cf.flags & contracts::GRID_BITS) == contracts::ATMOSPHERE) { // --- Assemble all inputs, to multiply by ice_to_hp matrix std::vector<blitz::Array<double, 1>> ival_I; for (auto model = models.begin(); model != models.end(); ++model) { // Assemble vector of the same GCM input variable from each ice model. ival_I.push_back(model->gcm_ivals_I[var_ix]); } ice2atm.multiply(ival_I, gcm_ivals[var_ix], true); gcm_ivals[var_ix].consolidate(); } else if ((cf.flags & contracts::GRID_BITS) == contracts::ELEVATION) { // --- Assemble all inputs, to send to Glint2 QP regridding std::map<int, blitz::Array<double,1>> f4s; for (auto model = models.begin(); model != models.end(); ++model) { int sheetno = model.key(); f4s.insert(std::make_pair(sheetno, model->gcm_ivals_I[var_ix])); } // Use previous return as our initial guess blitz::Array<double,1> initial3(maker_full->n3()); giss::to_blitz(gcm_ivals[var_ix], initial3); gcm_ivals[var_ix] = maker_full->iceinterp_to_hp( f4s, initial3, IceInterp::ICE, QPAlgorithm::SINGLE_QP); gcm_ivals[var_ix].consolidate(); } } // ----------------- Free Memory // (ONLY ON GCM ROOT) for (auto model = models.begin(); model != models.end(); ++model) { model->free_ovals_ivals_I(); } printf("END GCMCoupler::regrid_gcm_inputs_onroot\n"); }