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; } }
static PyObject *MatrixMaker_hp_to_iceinterp(PyMatrixMaker *self, PyObject *args, PyObject *kwds) { PyObject *ret_py = NULL; try { // Get arguments const char *ice_sheet_name_py; const char *dest_py = "ICE"; int fill_masked = 0; static char const *keyword_list[] = {"sheetname", "dest", "fill_masked", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "s|si", const_cast<char **>(keyword_list), &ice_sheet_name_py, &dest_py, &fill_masked)) { // Throw an exception... PyErr_SetString(PyExc_ValueError, "hp_to_iceinterp() 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 dest(giss::parse_enum<IceInterp>(dest_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 hp_to_iceinterp matrix from it auto ret_c(sheet->hp_to_iceinterp(dest, fill_masked)); // 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_hp_to_iceinterp()"); return 0; } }
static PyObject *MatrixMaker_area1(PyMatrixMaker *self, PyObject *args, PyObject *kwds) { printf("BEGIN MatrixMaker_area1()\n"); PyObject *ret_py = NULL; try { // Get arguments const char *ice_sheet_name_py; static char const *keyword_list[] = {"sheetname", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "s", const_cast<char **>(keyword_list), &ice_sheet_name_py)) { // Throw an exception... PyErr_SetString(PyExc_ValueError, "Bad arguments for area1()."); return 0; } glint2::MatrixMaker *maker = self->maker.get(); std::string const ice_sheet_name(ice_sheet_name_py); IceSheet *sheet = (*maker)[ice_sheet_name]; giss::MapSparseVector<int,double> area1_m; sheet->accum_areas(area1_m); blitz::Array<double,1> ret(maker->n1()); ret = 0; for (auto ii=area1_m.begin(); ii != area1_m.end(); ++ii) { ret(ii->first) = ii->second; } ret_py = giss::blitz_to_py(ret); return ret_py; } catch(...) { if (ret_py) Py_DECREF(ret_py); PyErr_SetString(PyExc_ValueError, "Error in MatrixMaker_ice_to_hp()"); return 0; } }
static PyObject *MatrixMaker_ice_to_interp(PyMatrixMaker *self, PyObject *args, PyObject *kwds) { printf("BEGIN MatrixMaker_ice_to_interp()\n"); PyObject *ret_py = NULL; try { // Get arguments const char *ice_sheet_name_py; PyObject *f2_py; // Should be [(1 : [...]), (2 : [...])] static char const *keyword_list[] = {"sheetname", "f2", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "sO", const_cast<char **>(keyword_list), &ice_sheet_name_py, &f2_py)) { // Throw an exception... PyErr_SetString(PyExc_ValueError, "Bad arguments for ice_to_interp()."); return 0; } glint2::MatrixMaker *maker = self->maker.get(); std::string const ice_sheet_name(ice_sheet_name_py); IceSheet *sheet = (*maker)[ice_sheet_name]; int dims[1] = {sheet->n2()}; auto f2(giss::py_to_blitz<double,1>(f2_py, "f2", 1, dims)); auto ret(sheet->ice_to_interp(f2)); ret_py = giss::blitz_to_py(ret); return ret_py; } catch(...) { if (ret_py) Py_DECREF(ret_py); PyErr_SetString(PyExc_ValueError, "Error in MatrixMaker_ice_to_hp()"); 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"); }
static PyObject *MatrixMaker_iceinterp_to_hp(PyMatrixMaker *self, PyObject *args, PyObject *kwds) { printf("BEGIN MatrixMaker_ice_to_hp()\n"); PyObject *ret_py = NULL; try { // Get arguments PyObject *f2s_py; // Should be [(1 : [...]), (2 : [...])] PyObject *initial_py = NULL; // array[n3] const char *src_py = "ICE"; const char *qp_algorithm_py = "SINGLE_QP"; static char const *keyword_list[] = {"f2s", "initial3", "src", "qp_algorithm", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O|Oss", const_cast<char **>(keyword_list), &f2s_py, &initial_py, &src_py, &qp_algorithm_py)) { // Throw an exception... PyErr_SetString(PyExc_ValueError, "Bad arguments for ice_to_hp()."); return 0; } auto src(giss::parse_enum<IceInterp>(src_py)); auto qp_algorithm(giss::parse_enum<QPAlgorithm>(qp_algorithm_py)); if (!PyList_Check(f2s_py)) { PyErr_SetString(PyExc_ValueError, "Argument must be a list."); return 0; } // Convert the Python dict to a C++ dict std::map<int, blitz::Array<double,1>> f2s; Py_ssize_t len = PyList_Size(f2s_py); for (int i=0; i < len; ++i) { PyObject *ii = PyList_GetItem(f2s_py, i); if (!PyTuple_Check(ii)) { PyErr_SetString(PyExc_ValueError, "List must contain tuples"); return 0; } char *sheetname_py; PyObject *f2_py; PyArg_ParseTuple(ii, "sO", &sheetname_py, &f2_py); printf("MatrixMaker_ice_to_hp(): Adding %s\n", sheetname_py); IceSheet *sheet = (*self->maker)[std::string(sheetname_py)]; int dims[1] = {src == IceInterp::ICE ? sheet->n2() : sheet->n4()}; auto f2(giss::py_to_blitz<double,1>(f2_py, "f2", 1, dims)); f2s.insert(std::make_pair(sheet->index, f2)); } // Get the blitz array from python int dims[1] = {self->maker->n3()}; blitz::Array<double,1> initial; if (initial_py) { initial.reference(giss::py_to_blitz<double,1>(initial_py, "initial", 1, dims)); } // Call! giss::VectorSparseVector<int, double> f3( self->maker->iceinterp_to_hp(f2s, initial, src, qp_algorithm)); // Copy output for return blitz::Array<double,1> ret(self->maker->n3()); giss::to_blitz(f3, ret); #if 0 ret = 0; for (auto ii = f3.begin(); ii != f3.end(); ++ii) { int i3 = ii->first; double val = ii->second; ret(i3) = val; } #endif ret_py = giss::blitz_to_py(ret); return ret_py; } catch(...) { if (ret_py) Py_DECREF(ret_py); PyErr_SetString(PyExc_ValueError, "Error in MatrixMaker_ice_to_hp()"); return 0; } }