00001 /* Copyright (C) 2008 00002 Patrick Eriksson <Patrick.Eriksson@rss.chalmers.se> 00003 Stefan Buehler <sbuehler@ltu.se> 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU General Public License as published by the 00007 Free Software Foundation; either version 2, or (at your option) any 00008 later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00018 USA. */ 00019 00020 00021 00022 /*=========================================================================== 00023 === File description 00024 ===========================================================================*/ 00025 00040 /*=========================================================================== 00041 === External declarations 00042 ===========================================================================*/ 00043 00044 #include <cmath> 00045 //#include <stdexcept> 00046 #include "arts.h" 00047 #include "check_input.h" 00048 #include "complex.h" 00049 #include "physics_funcs.h" 00050 #include "matpackIII.h" 00051 #include "math_funcs.h" 00052 #include "messages.h" 00053 #include "special_interp.h" 00054 #include "absorption.h" 00055 #include "interpolation.h" 00056 #include "fastem.h" 00057 #include "gridded_fields.h" 00058 00059 extern const Numeric DEG2RAD; 00060 extern const Numeric RAD2DEG; 00061 extern const Numeric EARTH_RADIUS; 00062 00063 extern const Index GFIELD4_IA_GRID; 00064 extern const Index GFIELD4_F_GRID; 00065 extern const Index GFIELD4_LAT_GRID; 00066 extern const Index GFIELD4_LON_GRID; 00067 00068 00069 00070 00071 /*=========================================================================== 00072 === Help functions (not WSMs) 00073 ===========================================================================*/ 00074 00076 00085 void surface_specular_los( 00086 VectorView los, 00087 const Index& atmosphere_dim ) 00088 { 00089 assert( atmosphere_dim >= 1 && atmosphere_dim <= 3 ); 00090 00091 if( atmosphere_dim == 1 ) 00092 { 00093 assert( los.nelem() == 1 ); 00094 assert( los[0] > 90 ); // Otherwise surface refl. not possible 00095 assert( los[0] <= 180 ); 00096 00097 los[0] = 180 - los[0]; 00098 } 00099 00100 else if( atmosphere_dim == 2 ) 00101 { 00102 assert( los.nelem() == 1 ); 00103 assert( abs(los[0]) <= 180 ); 00104 00105 los[0] = sign( los[0] ) * 180 - los[0]; 00106 } 00107 00108 else if( atmosphere_dim == 3 ) 00109 { 00110 assert( los.nelem() == 2 ); 00111 assert( los[0] >= 0 ); 00112 assert( los[0] <= 180 ); 00113 assert( abs( los[1] ) <= 180 ); 00114 00115 // Calculate LOS neglecting any tilt of the surface 00116 los[0] = 180 - los[0]; 00117 los[1] = los[1]; 00118 } 00119 } 00120 00121 00122 00124 00147 void surface_specular_R_and_b( 00148 MatrixView surface_rmatrix, 00149 VectorView surface_emission, 00150 const Complex& Rv, 00151 const Complex& Rh, 00152 const Numeric& f, 00153 const Index& stokes_dim, 00154 const Numeric& surface_skin_t ) 00155 { 00156 assert( surface_rmatrix.nrows() == stokes_dim ); 00157 assert( surface_rmatrix.ncols() == stokes_dim ); 00158 assert( surface_emission.nelem() == stokes_dim ); 00159 00160 // Expressions are derived in the surface chapter in the user guide 00161 00162 const Numeric rv = pow( abs(Rv), 2.0 ); 00163 const Numeric rh = pow( abs(Rh), 2.0 ); 00164 const Numeric rmean = ( rv + rh ) / 2; 00165 const Numeric B = planck( f, surface_skin_t ); 00166 00167 surface_rmatrix = 0.0; 00168 surface_emission = 0.0; 00169 00170 surface_rmatrix(0,0) = rmean; 00171 surface_emission[0] = B * ( 1 - rmean ); 00172 00173 if( stokes_dim > 1 ) 00174 { 00175 const Numeric rdiff = ( rv - rh ) / 2; 00176 00177 surface_rmatrix(1,0) = rdiff; 00178 surface_rmatrix(0,1) = rdiff; 00179 surface_rmatrix(1,1) = rmean; 00180 surface_emission[1] = -B * rdiff; 00181 00182 if( stokes_dim > 2 ) 00183 { 00184 const Complex a = Rh * conj(Rv); 00185 const Complex b = Rv * conj(Rh); 00186 const Numeric c = real( a + b ) / 2.0; 00187 00188 surface_rmatrix(2,2) = c; 00189 00190 if( stokes_dim > 3 ) 00191 { 00192 const Numeric d = imag( a - b ) / 2.0; 00193 00194 surface_rmatrix(3,2) = d; 00195 surface_rmatrix(2,3) = d; 00196 surface_rmatrix(3,3) = c; 00197 } 00198 } 00199 } 00200 /* 00201 cout << Rv << "\n"; 00202 cout << Rh << "\n"; 00203 cout << surface_rmatrix << "\n"; 00204 cout << surface_emission << "\n"; 00205 */ 00206 } 00207 00208 00209 00210 00211 00212 /*=========================================================================== 00213 === The functions (in alphabetical order) 00214 ===========================================================================*/ 00215 00216 /* Workspace method: Doxygen documentation will be auto-generated */ 00217 void InterpSurfaceFieldToRteGps( 00218 Numeric& outvalue, 00219 const Index& atmosphere_dim, 00220 const Vector& lat_grid, 00221 const Vector& lon_grid, 00222 const GridPos& rte_gp_lat, 00223 const GridPos& rte_gp_lon, 00224 const Matrix& field) 00225 { 00226 // Interpolate 00227 outvalue = interp_atmsurface_by_gp( atmosphere_dim, lat_grid, 00228 lon_grid, field, rte_gp_lat, rte_gp_lon ); 00229 00230 out3 << " Result = " << outvalue << "\n"; 00231 } 00232 00233 00234 00235 /* Workspace method: Doxygen documentation will be auto-generated */ 00236 void InterpSurfaceEmissivityFieldIncLatLon( 00237 Numeric& outvalue, 00238 const Index& atmosphere_dim, 00239 const Vector& rte_pos, 00240 const Vector& rte_los, 00241 const GField3& gfield ) 00242 { 00243 // Check input 00244 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 00245 if( rte_pos.nelem() != atmosphere_dim ) 00246 throw runtime_error( "Length of *rte_pos* must match *atmoshere_dim*." ); 00247 00248 // Interpolate 00249 // 00250 Numeric lat = 0, lon = 0; 00251 if( atmosphere_dim >= 2 ) 00252 lat = rte_pos[1]; 00253 if( atmosphere_dim == 3 ) 00254 lon = rte_pos[2]; 00255 // 00256 interp_gfield3( outvalue, gfield, atmosphere_dim, 180-abs(rte_los[0]), lat, 00257 lon, "Incidence angle", "Latitude", "Longitude" ); 00258 00259 out3 << " Result = " << outvalue << "\n"; 00260 } 00261 00262 00263 00264 /* Workspace method: Doxygen documentation will be auto-generated */ 00265 void r_geoidSpherical( 00266 // WS Output: 00267 Matrix& r_geoid, 00268 // WS Input: 00269 const Index& atmosphere_dim, 00270 const Vector& lat_grid, 00271 const Vector& lon_grid, 00272 const Numeric& r ) 00273 { 00274 // Check input (use dummy for *p_grid*). 00275 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 00276 chk_atm_grids( atmosphere_dim, Vector(2,2,-1), lat_grid, lon_grid ); 00277 00278 // What radius to use? 00279 Numeric r_local = r; 00280 if( r < 0 ) 00281 { r_local = EARTH_RADIUS; } 00282 00283 out2 << " Sets r_geoid to a sphere with a constant radius of " 00284 << r_local/1e3 << " km.\n"; 00285 00286 // Effective number of latitudes and longitudes 00287 Index nlat=1, nlon=1; 00288 if( atmosphere_dim >= 2 ) 00289 { nlat = lat_grid.nelem(); } 00290 if( atmosphere_dim >= 3 ) 00291 { nlon = lon_grid.nelem(); } 00292 00293 r_geoid.resize( nlat, nlon ); 00294 00295 r_geoid = r_local; 00296 00297 out3 << " nrows : " << r_geoid.nrows() << "\n"; 00298 out3 << " ncols : " << r_geoid.ncols() << "\n"; 00299 } 00300 00301 00302 00303 /* Workspace method: Doxygen documentation will be auto-generated */ 00304 void r_geoidWGS84( 00305 // WS Output: 00306 Matrix& r_geoid, 00307 // WS Input: 00308 const Index& atmosphere_dim, 00309 const Vector& lat_grid, 00310 const Vector& lon_grid, 00311 const Numeric& latitude_1d, 00312 const Numeric& azimuth_angle_1d ) 00313 { 00314 // Check input (use dummy for *p_grid*). 00315 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 00316 chk_atm_grids( atmosphere_dim, Vector(2,2,-1), lat_grid, lon_grid ); 00317 00318 // Radii of the reference ellipsiod and the values squared, where double 00319 // is used to avoid numerical problems. 00320 const Numeric rq = 6378.138e3, rp = 6356.752e3; 00321 const double rq2 = rq*rq, rp2 = rp*rp; 00322 00323 // For 1D the geoid is set to curvature radius for the point and direction 00324 // given by latitude_1d and azimuth_angle_1d. 00325 if( atmosphere_dim == 1 ) 00326 { 00327 chk_if_in_range( "latitude_1d", latitude_1d, -90., 90. ); 00328 chk_if_in_range( "azimuth_angle_1d", azimuth_angle_1d, -180., 180. ); 00329 00330 out2 << " Sets r_geoid to the curvature radius of the WGS-84 " 00331 << "reference ellipsiod.\n"; 00332 00333 r_geoid.resize(1,1); 00334 00335 // Cosine and sine of the latitude. The values are only used squared. 00336 double cv = cos( latitude_1d * DEG2RAD ); 00337 cv = cv * cv; 00338 double sv = sin( latitude_1d * DEG2RAD ); 00339 sv = sv * sv; 00340 00341 // Calculate NS and EW radius 00342 Numeric rns = rq2*rp2/pow(rq2*cv+rp2*sv,1.5); 00343 Numeric rew = rq2/sqrt(rq2*cv+rp2*sv); 00344 00345 // Calculate the curvature radius in the observation direction 00346 cv = cos( azimuth_angle_1d * DEG2RAD ); 00347 sv = sin( azimuth_angle_1d * DEG2RAD ); 00348 r_geoid(0,0) = 1/(cv*cv/rns+sv*sv/rew); 00349 } 00350 00351 else 00352 { 00353 out2 << " Sets r_geoid to the radius of the WGS-84 " 00354 << "reference ellipsiod.\n"; 00355 00356 // Number of latitudes 00357 const Index nlat = lat_grid.nelem(); 00358 00359 // Effective number of longitudes 00360 Index nlon; 00361 if( atmosphere_dim == 2 ) 00362 nlon = 1; 00363 else 00364 nlon = lon_grid.nelem(); 00365 00366 r_geoid.resize( nlat, nlon ); 00367 00368 Numeric sv, cv, rv; 00369 for( Index lat=0; lat<nlat; lat++ ) 00370 { 00371 // Check that the latutide is inside [-90,90] 00372 if( ( lat_grid[lat] < -90 ) || ( lat_grid[lat] > 90 ) ) 00373 { 00374 ostringstream os; 00375 os << "The accepted range for latitudes in this function is " 00376 << "[-90,90],\nbut a value of " << lat_grid[lat] 00377 << " was found."; 00378 throw runtime_error( os.str() ); 00379 } 00380 00381 // Cosine and sine of the latitude. 00382 cv = cos( lat_grid[lat] * DEG2RAD ); 00383 sv = sin( lat_grid[lat] * DEG2RAD ); 00384 00385 // The radius of the ellipsiod 00386 rv = sqrt( rq2*rp2 / ( rq2*sv*sv + rp2*cv*cv ) ); 00387 00388 // Loop longitudes and fill *r_geoid*. 00389 for( Index lon=0; lon<nlon; lon++ ) 00390 r_geoid(lat,lon) = rv; 00391 } 00392 } 00393 out3 << " nrows : " << r_geoid.nrows() << "\n"; 00394 out3 << " ncols : " << r_geoid.ncols() << "\n"; 00395 } 00396 00397 00398 00399 /* Workspace method: Doxygen documentation will be auto-generated */ 00400 void surfaceBlackbody( 00401 Matrix& surface_los, 00402 Tensor4& surface_rmatrix, 00403 Matrix& surface_emission, 00404 const Vector& f_grid, 00405 const Index& stokes_dim, 00406 const Numeric& surface_skin_t ) 00407 { 00408 chk_if_in_range( "stokes_dim", stokes_dim, 1, 4 ); 00409 chk_if_over_0( "surface_skin_t", surface_skin_t ); 00410 00411 out2 << " Sets variables to model a blackbody surface with a temperature " 00412 << " of " << surface_skin_t << " K.\n"; 00413 surface_los.resize(0,0); 00414 surface_rmatrix.resize(0,0,0,0); 00415 00416 const Index nf = f_grid.nelem(); 00417 surface_emission.resize( nf, stokes_dim ); 00418 surface_emission = 0.0; 00419 for( Index iv=0; iv<nf; iv++ ) 00420 { 00421 surface_emission(iv,0) = planck( f_grid[iv], surface_skin_t ); 00422 } 00423 } 00424 00425 00426 00427 /* Workspace method: Doxygen documentation will be auto-generated */ 00428 void surfaceFlatRefractiveIndex( 00429 Matrix& surface_los, 00430 Tensor4& surface_rmatrix, 00431 Matrix& surface_emission, 00432 const Vector& f_grid, 00433 const Index& stokes_dim, 00434 const Index& atmosphere_dim, 00435 const Vector& rte_los, 00436 const Numeric& surface_skin_t, 00437 const Matrix& complex_n ) 00438 { 00439 const Index nf = f_grid.nelem(); 00440 00441 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 00442 chk_if_in_range( "stokes_dim", stokes_dim, 1, 4 ); 00443 chk_if_over_0( "surface_skin_t", surface_skin_t ); 00444 00445 chk_matrix_ncols( "complex_n", complex_n, 2 ); 00446 // 00447 if( complex_n.nrows() != nf ) 00448 { 00449 ostringstream os; 00450 os << "The number of rows in *complex_n* should match length of *f_grid*." 00451 << "\n length of *f_grid* : " << nf 00452 << "\n rows in *complex_n* : " << complex_n.nrows() << "\n"; 00453 throw runtime_error( os.str() ); 00454 } 00455 00456 out2 << " Sets variables to model a flat surface\n"; 00457 out3 << " surface temperature: " << surface_skin_t << " K.\n"; 00458 00459 00460 surface_los.resize( 1, rte_los.nelem() ); 00461 surface_los(0,joker) = rte_los; 00462 surface_specular_los( surface_los(0,joker), atmosphere_dim ); 00463 00464 surface_emission.resize( nf, stokes_dim ); 00465 surface_rmatrix.resize( 1, nf, stokes_dim, stokes_dim ); 00466 00467 // Complex (amplitude) reflection coefficients 00468 Complex Rv, Rh; 00469 00470 for( Index iv=0; iv<nf; iv++ ) 00471 { 00472 // Set n2 (refractive index of surface medium) 00473 Complex n2( complex_n(iv,0), complex_n(iv,1) ); 00474 00475 // Amplitude reflection coefficients 00476 // 00477 fresnel( Rv, Rh, Numeric(1.0), n2, 180.0-abs(rte_los[0]) ); 00478 00479 // Fill reflection matrix and emission vector 00480 surface_specular_R_and_b( surface_rmatrix(0,iv,joker,joker), 00481 surface_emission(iv,joker), Rv, Rh, 00482 f_grid[iv], stokes_dim, surface_skin_t ); 00483 } 00484 } 00485 00486 00487 00488 /* Workspace method: Doxygen documentation will be auto-generated */ 00489 void surfaceFlatVaryingEmissivity( 00490 Matrix& surface_los, 00491 Tensor4& surface_rmatrix, 00492 Matrix& surface_emission, 00493 const Vector& f_grid, 00494 const Index& stokes_dim, 00495 const Index& atmosphere_dim, 00496 const Vector& rte_los, 00497 const Numeric& surface_skin_t, 00498 const Vector& surface_emissivity ) 00499 { 00500 chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 00501 chk_if_in_range( "stokes_dim", stokes_dim, 1, 4 ); 00502 chk_if_over_0( "surface_skin_t", surface_skin_t ); 00503 00504 const Index nf = f_grid.nelem(); 00505 00506 if( surface_emissivity.nelem() != nf ) 00507 { 00508 ostringstream os; 00509 os << "The number of elements in *surface_emissivity* should match\n" 00510 << "length of *f_grid*." 00511 << "\n length of *f_grid* : " << nf 00512 << "\n length of *surface_emissivity* : " << surface_emissivity.nelem() 00513 << "\n"; 00514 throw runtime_error( os.str() ); 00515 } 00516 00517 if( min(surface_emissivity) < 0 || max(surface_emissivity) > 1 ) 00518 { 00519 throw runtime_error( 00520 "All values in *surface_emissivity* must be inside [0,1]." ); 00521 } 00522 00523 out2 << " Sets variables to model a flat surface\n"; 00524 out3 << " surface temperature: " << surface_skin_t << " K.\n"; 00525 00526 surface_los.resize( 1, rte_los.nelem() ); 00527 surface_los(0,joker) = rte_los; 00528 surface_specular_los( surface_los(0, joker) , atmosphere_dim ); 00529 00530 surface_emission.resize( nf, stokes_dim ); 00531 surface_rmatrix.resize(1,nf,stokes_dim,stokes_dim); 00532 surface_rmatrix = 0.0; 00533 surface_emission = 0.0; 00534 00535 for( Index iv=0; iv<nf; iv++ ) 00536 { 00537 surface_emission(iv,0) = surface_emissivity[iv] * 00538 planck( f_grid[iv], surface_skin_t ); 00539 for( Index is=0; is<stokes_dim; is++ ) 00540 { surface_rmatrix(0,iv,is,is) = 1 - surface_emissivity[iv]; } 00541 } 00542 } 00543 00544 00545 00546 /* Workspace method: Doxygen documentation will be auto-generated */ 00547 void surfaceFlatSingleEmissivity( 00548 Matrix& surface_los, 00549 Tensor4& surface_rmatrix, 00550 Matrix& surface_emission, 00551 const Vector& f_grid, 00552 const Index& stokes_dim, 00553 const Index& atmosphere_dim, 00554 const Vector& rte_los, 00555 const Numeric& surface_skin_t, 00556 const Numeric& surface_emissivity ) 00557 { 00558 chk_if_in_range( "surface_emissivity", surface_emissivity, 0, 1 ); 00559 00560 Vector a_vector( f_grid.nelem(), surface_emissivity ); 00561 00562 surfaceFlatVaryingEmissivity( surface_los, surface_rmatrix, surface_emission, 00563 f_grid, stokes_dim, atmosphere_dim, rte_los, 00564 surface_skin_t, a_vector ); 00565 } 00566 00567 00568 00569 00570 00571 00572 00573 00574 00575 00576 // 00577 // 00578 // Old stuff: 00579 // 00580 // 00581 00582 00583 /* Workspace method: Doxygen documentation will be auto-generated */ 00584 // void surfaceEmissivityInterpolate( 00585 // Matrix& surface_los, 00586 // Tensor4& surface_rmatrix, 00587 // Matrix& surface_emission, 00588 // const Vector& f_grid, 00589 // const GridPos& rte_gp_lat, 00590 // const GridPos& rte_gp_lon, 00591 // const Index& stokes_dim, 00592 // const Index& atmosphere_dim, 00593 // const Vector& rte_los, 00594 // const Numeric& surface_skin_t, 00595 // const Matrix& surface_emissivity_field) 00596 // { 00597 // const Index nf = f_grid.nelem(); 00598 // Numeric e; 00599 // Vector itw(4); 00600 // surface_los.resize( 1, rte_los.nelem() ); 00601 // surface_los(0,joker) = rte_los; 00602 // surface_specular_los( surface_los(0, joker) , atmosphere_dim ); 00603 00604 // surface_emission.resize( nf, stokes_dim ); 00605 // surface_rmatrix.resize(1,nf,stokes_dim,stokes_dim); 00606 // surface_rmatrix = 0.0; 00607 // surface_emission = 0.0; 00608 00609 // interpweights(itw,rte_gp_lat,rte_gp_lon); 00610 // e=interp(itw,surface_emissivity_field,rte_gp_lat,rte_gp_lon); 00611 // for( Index iv=0; iv<nf; iv++ ) 00612 // { 00613 // surface_emission(iv,0) = e * planck( f_grid[iv], surface_skin_t ); 00614 // for( Index is=0; is<stokes_dim; is++ ) 00615 // { surface_rmatrix(0,iv,is,is) = 1 - e; } 00616 // } 00617 // } 00618 00619 00620 00621 // //! surfaceCalc 00622 // /*! 00623 // See the the online help (arts -d FUNCTION_NAME) 00624 00625 // \author Patrick Eriksson 00626 // \date 2004-05-21 00627 // */ 00628 // void surfaceCalc( 00629 // Matrix& iy, 00630 // ArrayOfTensor4& diy_dvmr, 00631 // ArrayOfTensor4& diy_dt, 00632 // Ppath& ppath, 00633 // Ppath& ppath_step, 00634 // ArrayOfPpath& ppath_array, 00635 // Index& ppath_array_index, 00636 // const Vector& rte_pos, 00637 // const Vector& rte_los, 00638 // const Agenda& ppath_step_agenda, 00639 // const Agenda& rte_agenda, 00640 // const Agenda& iy_space_agenda, 00641 // const Agenda& iy_surface_agenda, 00642 // const Agenda& iy_cloudbox_agenda, 00643 // const Index& atmosphere_dim, 00644 // const Vector& p_grid, 00645 // const Vector& lat_grid, 00646 // const Vector& lon_grid, 00647 // const Tensor3& z_field, 00648 // const Tensor3& t_field, 00649 // const Tensor4& vmr_field, 00650 // const Matrix& r_geoid, 00651 // const Matrix& z_surface, 00652 // const Index& cloudbox_on, 00653 // const ArrayOfIndex& cloudbox_limits, 00654 // const Vector& f_grid, 00655 // const Index& stokes_dim, 00656 // const Index& ppath_array_do, 00657 // const ArrayOfIndex& rte_do_vmr_jacs, 00658 // const Index& rte_do_t_jacs, 00659 // const Matrix& surface_los, 00660 // const Tensor4& surface_rmatrix, 00661 // const Matrix& surface_emission ) 00662 // { 00663 // // Some sizes 00664 // const Index nf = f_grid.nelem(); 00665 // const Index nlos = surface_los.nrows(); 00666 00667 00668 // //--- Check input ----------------------------------------------------------- 00669 // if( nlos ) // nlos = 0 if blackbody ground and some checks are not needed 00670 // { 00671 // if( surface_los.ncols() != rte_los.nelem() ) 00672 // throw runtime_error( 00673 // "Number of columns in *surface_los* is not correct." ); 00674 // if( nlos != surface_rmatrix.nbooks() ) 00675 // throw runtime_error( 00676 // "Mismatch in size of *surface_los* and *surface_rmatrix*." ); 00677 // if( surface_rmatrix.npages() != nf ) 00678 // throw runtime_error( 00679 // "Mismatch in size of *surface_rmatrix* and *f_grid*." ); 00680 // if( surface_rmatrix.ncols() != stokes_dim || 00681 // surface_rmatrix.ncols() != stokes_dim ) throw runtime_error( 00682 // "Mismatch between size of *surface_rmatrix* and *stokes_dim*." ); 00683 // } 00684 // if( surface_emission.ncols() != stokes_dim ) 00685 // throw runtime_error( 00686 // "Mismatch between size of *surface_emission* and *stokes_dim*." ); 00687 // if( surface_emission.nrows() != nf ) 00688 // throw runtime_error( 00689 // "Mismatch in size of *surface_emission* and f_grid*." ); 00690 // //--------------------------------------------------------------------------- 00691 00692 // ppath_array_index=0; 00693 00694 00695 // // Variables to hold downvelling radiation 00696 // Tensor3 I( nlos, nf, stokes_dim ); 00697 00698 // // Loop *surface_los*-es. If no such LOS, we are ready. 00699 // if( nlos > 0 ) 00700 // { 00701 // // Make local version of *ppath* that later must be restored 00702 // Ppath pp_copy; 00703 // ppath_init_structure( pp_copy, atmosphere_dim, ppath.np ); 00704 // ppath_copy( pp_copy, ppath ); 00705 // // 00706 // const Index pai = ppath_array_index; 00707 00708 // for( Index ilos=0; ilos<nlos; ilos++ ) 00709 // { 00710 // // Calculate downwelling radiation for LOS ilos 00711 // iy_calc( iy, ppath, ppath_step, 00712 // ppath_array_index, ppath_array, 00713 // diy_dvmr, diy_dt, 00714 // ppath_step_agenda, rte_agenda, 00715 // iy_space_agenda, iy_surface_agenda, iy_cloudbox_agenda, 00716 // atmosphere_dim, p_grid, lat_grid, lon_grid, z_field, 00717 // t_field, vmr_field, 00718 // r_geoid, z_surface, cloudbox_on, cloudbox_limits, 00719 // rte_pos, surface_los(ilos,joker), 00720 // f_grid, stokes_dim, 00721 // ppath_array_do, 00722 // rte_do_vmr_jacs, rte_do_t_jacs ); 00723 00724 // I(ilos,joker,joker) = iy; 00725 00726 // // Include reflection matrix in jacobian quantities 00727 // // 00728 // // Assume polarisation effects in surface_rmatrix 00729 // // (not of any impoartnce if stokes_dim=1) 00730 // const bool pol_r = true; 00731 // // 00732 // if( rte_do_vmr_jacs.nelem() ) 00733 // { 00734 // for( Index iv=0; iv<nf; iv++ ) 00735 // { 00736 // include_trans_in_diy_dq( diy_dvmr, iv, pol_r, 00737 // surface_rmatrix(ilos,iv,joker,joker), 00738 // ppath_array, ppath_array_index ); 00739 // } 00740 // } 00741 // if( rte_do_t_jacs ) 00742 // { 00743 // for( Index iv=0; iv<nf; iv++ ) 00744 // { 00745 // include_trans_in_diy_dq( diy_dt, iv, pol_r, 00746 // surface_rmatrix(ilos,iv,joker,joker), 00747 // ppath_array, ppath_array_index ); 00748 // } 00749 // } 00750 00751 // // Reset *ppath_array_index* 00752 // ppath_array_index = pai; 00753 // } 00754 00755 // // Copy data back to *ppath*. 00756 // ppath_init_structure( ppath, atmosphere_dim, pp_copy.np ); 00757 // ppath_copy( ppath, pp_copy ); 00758 // } 00759 00760 // surface_calc( iy, I, surface_los, surface_rmatrix, surface_emission ); 00761 // } 00762 00763 00764 00765 // //! surfaceSpecular 00766 // /*! 00767 // See the the online help (arts -d FUNCTION_NAME) 00768 00769 // \author Patrick Eriksson 00770 // \date 2004-05-20 00771 // */ 00772 // void surfaceSpecular( 00773 // Matrix& iy, 00774 // Ppath& ppath, 00775 // Ppath& ppath_step, 00776 // Vector& rte_pos, 00777 // GridPos& rte_gp_p, 00778 // GridPos& rte_gp_lat, 00779 // GridPos& rte_gp_lon, 00780 // Vector& rte_los, 00781 // const Agenda& ppath_step_agenda, 00782 // const Agenda& rte_agenda, 00783 // const Agenda& iy_space_agenda, 00784 // const Agenda& iy_surface_agenda, 00785 // const Agenda& iy_cloudbox_agenda, 00786 // const Index& atmosphere_dim, 00787 // const Vector& p_grid, 00788 // const Vector& lat_grid, 00789 // const Vector& lon_grid, 00790 // const Tensor3& z_field, 00791 // const Matrix& r_geoid, 00792 // const Matrix& z_surface, 00793 // const Index& cloudbox_on, 00794 // const ArrayOfIndex& cloudbox_limits, 00795 // const Vector& f_grid, 00796 // const Index& stokes_dim, 00797 // const Numeric& surface_t, 00798 // const Vector& surface_rv, 00799 // const Vector& surface_rh ) 00800 // { 00801 // // Check input 00802 // if( surface_rv.nelem() != f_grid.nelem() ) 00803 // throw runtime_error( "Lengths of *surface_rv* and *f_grid* differ." ); 00804 // if( surface_rh.nelem() != f_grid.nelem() ) 00805 // throw runtime_error( "Lengths of *surface_rh* and *f_grid* differ." ); 00806 // if( max(surface_rv)<0 || max(surface_rv)>1 ) 00807 // throw runtime_error( 00808 // "*surface_rv* can only contain values in range [0,1]." ); 00809 // if( max(surface_rh)<0 || max(surface_rh)>1 ) 00810 // throw runtime_error( 00811 // "*surface_rh* can only contain values in range [0,1]." ); 00812 00813 00814 00815 // // Make local version of *ppath* that later must be restored 00816 // Ppath pp_copy; 00817 // ppath_init_structure( pp_copy, atmosphere_dim, ppath.np ); 00818 // ppath_copy( pp_copy, ppath ); 00819 00820 // // Determine specular direction 00821 // surface_specular_los( rte_los, atmosphere_dim ); 00822 00823 // // Calculate downwelling radiation and put in local variable 00824 // Vector pos( rte_pos.nelem() ), los( rte_los.nelem() ); 00825 // // 00826 // pos = rte_pos; 00827 // los = rte_los; 00828 // // 00829 // iy_calc( iy, ppath, ppath_step, 00830 // ppath_step_agenda, rte_agenda, iy_space_agenda, 00831 // iy_surface_agenda, iy_cloudbox_agenda, atmosphere_dim, p_grid, 00832 // lat_grid, lon_grid, z_field, r_geoid, z_surface, cloudbox_on, 00833 // cloudbox_limits, pos, los, f_grid, stokes_dim ); 00834 // // 00835 // Matrix idown( iy.nrows(), iy.ncols() ); 00836 // idown = iy; 00837 00838 // // Add up reflected radiation and surface emission 00839 // // 00840 // Vector b(stokes_dim); // Surface emission Stokes vector 00841 // Matrix R(stokes_dim, stokes_dim); // Reflection matrix 00842 // // 00843 // for( Index i=0; i<f_grid.nelem(); i++ ) 00844 // { 00845 // // Set up variables 00846 00847 // // THIS PART IS NOT COMPLETE. THERE SHALL BE MORE TERMS 00848 // const Numeric rmean = ( surface_rh[i] + surface_rv[i] ) / 2; 00849 // b[0] = ( 1 - rmean ) * planck( f_grid[i], surface_t ); 00850 // for( Index j=0; j<stokes_dim; j++ ) 00851 // { R(j,j) = rmean; } 00852 00853 // // Make math 00854 // mult( iy(i,joker), R, iy(i,joker) ); // 00855 // iy(i,joker) += b; 00856 // } 00857 00858 // // Copy data back to *ppath*. 00859 // ppath_init_structure( ppath, atmosphere_dim, pp_copy.np ); 00860 // ppath_copy( ppath, pp_copy ); 00861 // } 00862 00863 00864 // agenda_data.push_back 00865 // (AgRecord 00866 // ( NAME( "surface_agenda" ), 00867 // DESCRIPTION 00868 // ( 00869 // "Describes the properties of the surface to consider when there is a\n" 00870 // "surface reflection.\n" 00871 // "\n" 00872 // "The surface properties are described by the WSVs\n" 00873 // "*surface_emission*, *surface_los* and *surface_refl_coeffs*.\n" 00874 // "\n" 00875 // "The upwelling radiation from the surface is calculated as the sum\n" 00876 // "of *surface_emission* and the spectra calculated for the directions\n" 00877 // "given by *surface_los*, multiplicated with the weights in\n" 00878 // "*surface_refl_coeffs*. Or (for frequency i): \n" 00879 // " i_up = i_emission + sum_over_los( W*i_down ) \n" 00880 // "where i_up is the upwelling radiation, i_emission is row i of\n" 00881 // "*surface_emission*, W is the reflection matrix in \n" 00882 // "*surface_refl_coeffs* for the frequency and LOS of concern and \n" 00883 // "i_down is the downwelling radiation for the LOS given in\n" 00884 // "*surface_los*. \n" 00885 // "\n" 00886 // "With other words, the scattering properties of the surface are \n" 00887 // "described by the variables *surface_los* and *surface_refl_coeffs*.\n" 00888 // "\n" 00889 // "A function calling this agenda shall set *rte_los* and *rte_gp_XXX*\n" 00890 // "to match the line-of-sight and position at the surface reflection\n" 00891 // "point.\n" 00892 // "\n" 00893 // "See further the user guide.\n" 00894 // "\n" 00895 // "Usage: Called from *RteCalc*." 00896 // ), 00897 // OUTPUT( surface_emission_, surface_los_, surface_refl_coeffs_ ), 00898 // INPUT( f_grid_, stokes_dim_, rte_gp_p_, rte_gp_lat_, rte_gp_lon_, 00899 // rte_los_, r_geoid_, z_surface_, t_field_ ))); 00900 00901 00902 00903 00904 // wsv_data.push_back 00905 // (WsvRecord 00906 // ( NAME( "surface_agenda" ), 00907 // DESCRIPTION 00908 // ( 00909 // "See agendas.cc." 00910 // ), 00911 // GROUP( Agenda_ ))); 00912 00913 00914 // wsv_data.push_back 00915 // (WsvRecord 00916 // ( NAME( "surface_emission_field" ), 00917 // DESCRIPTION 00918 // ( 00919 // "The emission from the surface which is stored in latitude and \n" 00920 // " longitude grids.\n" 00921 // "\n" 00922 // "An emissivity calculation using the method *surfaceFastem* \n" 00923 // "calculates surface_emission_field at the same grid points as \n" 00924 // "lat_grid and lon_grid. The surface_emission_field is then \n" 00925 // "interpolated on to the grid crossing position using the \n" 00926 // "method *surfaceInterpolate* to get value of *surface_emission*\n" 00927 // "at a specified position. \n" 00928 // "\n" 00929 // "Usage: Output from *surfaceFastem*. \n" 00930 // "\n" 00931 // "Unit: W / (m^2 Hz sr)\n" 00932 // "\n" 00933 // "Dimensions: [lat_grid, lon_grid, f_grid, stokes_dim ]" 00934 // ), 00935 // GROUP( Tensor4_ ))); 00936 00937 // wsv_data.push_back 00938 // (WsvRecord 00939 // ( NAME( "surface_emissivity_field" ), 00940 // DESCRIPTION 00941 // ( 00942 // "This variable holds the value of surface emissivity.\n" 00943 // "\n" 00944 // "This field is stored in a Tensor3 where the first two dimensions\n" 00945 // "holds the latitude and longitude grid and the third dimension holds\n" 00946 // "the value for each *stokes_dim*. The surface_emissivity_field takes \n" 00947 // "values between 0 and 1. If only a prescribed value of surface \n" 00948 // "emissivity is to be used, then set the value accordingly, and use the method \n" 00949 // "*surfaceNoScatteringSingleEmissivity* in the *surface_agenda*. The value\n" 00950 // "of the field is set to -1 if one wants to calculate the surface emissivity \n" 00951 // "using FASTEM. Accordingly, the method surfaceFastem has to be used in\n" 00952 // "*surface_agenda*\n" 00953 // "\n" 00954 // "Usage: Set from the control file as a workspace variable. \n" 00955 // "\n" 00956 // "Units: -\n" 00957 // "\n" 00958 // "Dimensions: [ lat_grid, lon_grid, stokes_dim ]" 00959 // ), 00960 // GROUP( Tensor3_ ))); 00961 00962 // wsv_data.push_back 00963 // (WsvRecord 00964 // ( NAME( "surface_fastem_constants" ), 00965 // DESCRIPTION 00966 // ( 00967 // "This variable holds some constant parameters used in fastem model.\n" 00968 // "\n" 00969 // "There are 59 ocean surface emissivity model constants that are \n" 00970 // "used in the fastem calculations.\n" 00971 // "\n" 00972 // "Usage: Read in from file to be used as input for fastem calculations. \n" 00973 // "\n" 00974 // "Units: -\n" 00975 // "\n" 00976 // "Size: [ 59 ]" 00977 // ), 00978 // GROUP( Vector_ ))); 00979 00980 00981 // wsv_data.push_back 00982 // (WsvRecord 00983 // ( NAME( "surface_refl_coeffs_field" ), 00984 // DESCRIPTION 00985 // ( 00986 // "The reflection coefficients from the directions given by\n" 00987 // "*surface_los* to the direction of interest at the lat_grid\n" 00988 // "and lon_grid. \n" 00989 // "\n" 00990 // "The difference with *surface_refl_coeffs* is that, here the \n" 00991 // "coefficient matrix is held in latitude and longitude grid \n" 00992 // "positions whereas *surface_refl_coeffs* corresponds to only\n" 00993 // "a specific position. Like *surface_emission_field*, \n" 00994 // "*surface_refl_coeffs_field* can also be calculated using the \n" 00995 // "method *surfaceFastem*. The variable *surface_refl_coeffs_field*\n" 00996 // "is interpolated onto the specific grid crossing points using the\n" 00997 // "method *surfaceInterpolate*. \n" 00998 // "\n" 00999 // "See further *surface_refl_coeffs* and *surfaceInterpolate*.\n" 01000 // "\n" 01001 // "Usage: Output from *surfaceFastem*. \n" 01002 // "\n" 01003 // "Units: -\n" 01004 // "\n" 01005 // "Dimensions: [ lat_grid, lon_grid, surface_los, f_grid, stokes_dim, stokes_dim ]" 01006 // ), 01007 // GROUP( Tensor6_ ))); 01008 01009 // wsv_data.push_back 01010 // (WsvRecord 01011 // ( NAME( "surface_temperature" ), 01012 // DESCRIPTION 01013 // ( 01014 // "This variable holds the surface temperature values for all \n" 01015 // "latitude - longitude grid points. \n" 01016 // "\n" 01017 // "Usage: Input to FASTEM calculations. Can be set from the control file \n" 01018 // "as a workspace variable. \n" 01019 // "\n" 01020 // "Units: K" 01021 // "\n" 01022 // "Dimensions: [ lat_grid, lon_grid, 1 ]" 01023 // ), 01024 // GROUP( Tensor3_ ))); 01025 01026 // wsv_data.push_back 01027 // (WsvRecord 01028 // ( NAME( "surface_wind_field" ), 01029 // DESCRIPTION 01030 // ( 01031 // "This variable gives the u- and v- components of surface wind.\n" 01032 // "\n" 01033 // "This field is stored in a Tensor3 where the first two dimensions\n" 01034 // "holds the latitude and longitude grid and the third dimension holds\n" 01035 // "the value for u- and v- components respectively. The \n" 01036 // "surface_wind_field(lat_grid, lon_grid, 0) gives the u- component and \n" 01037 // "surface_wind_field(lat_grid, lon_grid, 1) gives the v- component in m/s.\n" 01038 // "\n" 01039 // "Usage: Input to FASTEM calculations. Can be set from the control file \n" 01040 // "as a workspace variable. \n" 01041 // "\n" 01042 // "Units: m/s" 01043 // "\n" 01044 // "Dimensions: [ lat_grid, lon_grid, 2 ]" 01045 // ), 01046 // GROUP( Tensor3_ ))); 01047 01048 01049 01050 01051 // //! surfaceNoScatteringSingleEmissivity 01052 // /*! 01053 // See the the online help (arts -d FUNCTION_NAME) 01054 01055 // \author Patrick Eriksson 01056 // \date 2002-09-22 01057 // */ 01058 // void surfaceNoScatteringSingleEmissivity( 01059 // Matrix& surface_emission, 01060 // Matrix& surface_los, 01061 // Tensor4& surface_refl_coeffs, 01062 // const Vector& f_grid, 01063 // const Index& stokes_dim, 01064 // const GridPos& rte_gp_p, 01065 // const GridPos& rte_gp_lat, 01066 // const GridPos& rte_gp_lon, 01067 // const Vector& rte_los, 01068 // const Index& atmosphere_dim, 01069 // const Vector& p_grid, 01070 // const Vector& lat_grid, 01071 // const Vector& lon_grid, 01072 // const Matrix& r_geoid, 01073 // const Matrix& z_surface, 01074 // const Tensor3& t_field, 01075 // const Numeric& e ) 01076 // { 01077 // //--- Check input ----------------------------------------------------------- 01078 // chk_if_in_range( "stokes_dim", stokes_dim, 1, 4 ); 01079 // chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 01080 // chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid ); 01081 // chk_atm_surface( "r_geoid", r_geoid, atmosphere_dim, lat_grid, lon_grid ); 01082 // chk_atm_surface( "z_surface", z_surface, atmosphere_dim, lat_grid, lon_grid ); 01083 // chk_atm_field( "t_field", t_field, atmosphere_dim, p_grid, lat_grid, 01084 // lon_grid ); 01085 // chk_if_in_range( "the keyword *e*", e, 0, 1 ); 01086 // //--------------------------------------------------------------------------- 01087 01088 // out2 << 01089 // " Sets the surface to have no scattering and a constant emissivity.\n"; 01090 // out3 << 01091 // " Surface temperature is obtained by interpolation of *t_field*.\n"; 01092 01093 // // Some sizes 01094 // const Index nf = f_grid.nelem(); 01095 01096 // // Resize output arguments 01097 // surface_emission.resize( nf, stokes_dim ); 01098 // surface_los.resize( 1, rte_los.nelem() ); 01099 // surface_refl_coeffs.resize( 1, nf, stokes_dim, stokes_dim ); 01100 // surface_refl_coeffs = 0; 01101 01102 // // Determine the temperature at the point of the surface reflection 01103 // const Numeric t = interp_atmfield_by_gp( atmosphere_dim, p_grid, lat_grid, 01104 // lon_grid, t_field, rte_gp_p, rte_gp_lat, rte_gp_lon ); 01105 01106 // out3 << " Surface temperature is : " << t << "\n"; 01107 01108 // // Fill surface_emission and surface_refl_coeffs 01109 // for( Index i=0; i<nf; i++ ) 01110 // { 01111 // surface_emission(i,0) = e * planck( f_grid[i], t ); 01112 // surface_refl_coeffs(0,i,0,0) = 1 - e; 01113 // for( Index is=1; is<stokes_dim; is++ ) 01114 // { 01115 // surface_emission(i,is) = 0; 01116 // surface_refl_coeffs(0,i,is,is) = 1 - e; 01117 // } 01118 // // Note that other elements of surface_refl_coeffs are set to 0 above. 01119 // } 01120 01121 // // Calculate LOS for downwelling radiation 01122 // surface_specular_los( surface_los(0,joker), atmosphere_dim, r_geoid, 01123 // z_surface, lat_grid, lon_grid, rte_gp_lat,rte_gp_lon, rte_los ); 01124 01125 // out3 << " Zenith angle for upwelling radiation is : " 01126 // << rte_los[0] << "\n"; 01127 // if( atmosphere_dim > 2 ) 01128 // { 01129 // out3 << " Azimuth angle for upwelling radiation is : " 01130 // << rte_los[1] << "\n"; 01131 // } 01132 // out3 << " Zenith angle for downwelling radiation is : " 01133 // << surface_los(0,0) << "\n"; 01134 // if( atmosphere_dim > 2 ) 01135 // { 01136 // out3 << " Azimuth angle for downwelling radiation is: " 01137 // << surface_los(0,1) << "\n"; 01138 // } 01139 // } 01140 01141 01142 // //! surfaceFastem 01143 // /*! 01144 // The method decides whether to use *surfaceNoScatteringSingleEmissivity* or 01145 // *surfaceFastem*. If *surfaceFastem*, then calculates surface emissivity using 01146 // fastem model implementation. 01147 // The decision whether to use *surfaceNoScatteringSingleEmissivity* or 01148 // *surfaceFastem* is made based on the value of the first element of 01149 // *surface_emissivity_field*. If this value is set to be between 0 and 1 01150 // *surface_emissivity_field* will be returned with the same value. If this 01151 // value is -1 *surfaceFastem* will calculate the emissivity based on the 01152 // fastem model implementation in ARTS. The output of this function is 01153 // *surface_emission_field* and *surface_refl_coeffs_field+ stored in the 01154 // latitude and longitude grid points. 01155 01156 01157 // \author Sreerekha Ravi 01158 // \date 2004-08-10 01159 // */ 01160 01161 // void surfaceFastem( 01162 // Tensor3& surface_emissivity_field, 01163 // Tensor4& surface_emission_field, 01164 // Tensor6& surface_refl_coeffs_field, 01165 // const Vector& f_grid, 01166 // const Index& stokes_dim, 01167 // const Index& atmosphere_dim, 01168 // const Vector& p_grid, 01169 // const Vector& lat_grid, 01170 // const Vector& lon_grid, 01171 // const Matrix& r_geoid, 01172 // const Matrix& z_surface, 01173 // const Tensor3& t_field, 01174 // const Vector& surface_fastem_constants, 01175 // const Tensor3& surface_wind_field, 01176 // const Tensor3& surface_temperature) 01177 // { 01178 // //--- Check input ----------------------------------------------------------- 01179 // chk_if_in_range( "stokes_dim", stokes_dim, 1, 4 ); 01180 // chk_if_in_range( "atmosphere_dim", atmosphere_dim, 1, 3 ); 01181 // chk_atm_grids( atmosphere_dim, p_grid, lat_grid, lon_grid ); 01182 // chk_atm_surface( "r_geoid", r_geoid, atmosphere_dim, lat_grid, lon_grid ); 01183 // chk_atm_surface( "z_surface", z_surface, atmosphere_dim, lat_grid, lon_grid ); 01184 // chk_atm_field( "t_field", t_field, atmosphere_dim, p_grid, lat_grid, 01185 // lon_grid ); 01186 // //----------------------------------------------------------------------------- 01187 // const Index nf = f_grid.nelem(); 01188 01189 // surface_emission_field.resize(lat_grid.nelem(), lon_grid.nelem(), 01190 // f_grid.nelem(), stokes_dim); 01191 // surface_refl_coeffs_field.resize(lat_grid.nelem(), lon_grid.nelem(), 01192 // 1, f_grid.nelem(), stokes_dim, stokes_dim); 01193 01194 // if (surface_emissivity_field(0, 0, 0) >= 0|| 01195 // surface_emissivity_field(0, 0, 0) <= 1.0) 01196 // { 01197 // return; 01198 // } 01199 // else 01200 // if (surface_emissivity_field(0, 0, 0) == -1) 01201 // { 01202 // //call FASTEM functions for each latitude and longitude grid 01203 // //points 01204 // for (Index lat_ind = 0; lat_ind < lat_grid.nelem(); ++ lat_ind) 01205 // { 01206 // for (Index lon_ind = 0; lon_ind < lon_grid.nelem(); ++ lon_ind) 01207 // { 01208 01209 // for( Index i=0; i<nf; i++ ) 01210 // { 01211 // //Calculate surf_emis_field using fastem 01212 // fastem(surface_emissivity_field(lat_ind, lon_ind, joker), 01213 // surface_temperature(lat_ind, lon_ind, 0), 01214 // surface_wind_field(lat_ind, lon_ind, joker) , 01215 // surface_fastem_constants, f_grid[i]); 01216 01217 // //Calculate emission by multiplying surface 01218 // //emissivity with surface temperature. 01219 // surface_emission_field(lat_ind, lon_ind, i, joker) = 01220 // surface_emissivity_field(lat_ind, lon_ind, joker) * 01221 // planck( f_grid[i], surface_temperature (lat_ind, lon_ind, 0) ); 01222 01223 // for( Index is=0; is<stokes_dim; is++ ) 01224 // { 01225 // surface_refl_coeffs_field(lat_ind, lon_ind, 0,i,is,is) = 01226 // 1 - surface_emission_field(lat_ind, lon_ind, i, is); 01227 // } //stokes_dim 01228 // }//frequency grid 01229 // }//lon grid 01230 // }//lat_grid 01231 // }// if fastem 01232 // }// end of function 01233 01234 01235 01236 // //! surfaceTreatAsBlackbody 01237 // /*! 01238 // See the the online help (arts -d FUNCTION_NAME) 01239 01240 // \author Patrick Eriksson 01241 // \date 2002-09-17 01242 // */ 01243 01244 01245 01246 01247 // md_data_raw.push_back 01248 // ( MdRecord 01249 // ( NAME("surfaceFastem"), 01250 // DESCRIPTION 01251 // ( 01252 // "The method decides whether to use *surfaceNoScatteringSingleEmissivity* or \n" 01253 // "*surfaceFastem*. If *surfaceFastem*, then calculates surface emissivity using\n" 01254 // "fastem model implementation.\n" 01255 // "\n" 01256 // "The decision whether to use *surfaceNoScatteringSingleEmissivity* or\n" 01257 // "*surfaceFastem* is made based on the value of the first element of \n" 01258 // "surface_emissivity_field. If this value is set to be between 0 and 1\n" 01259 // "*surface_emissivity_field* will be returned with the same value. If this \n" 01260 // "value is -1 *surfaceFastem* will calculate the emissivity based on the \n" 01261 // "fastem model implementation in ARTS. The output of this function is \n" 01262 // "*surface_emission_field* and *surface_refl_coeffs_field* stored in the\n" 01263 // "latitude and longitude grid points. \n" 01264 // ), 01265 // OUTPUT( surface_emissivity_field_, surface_emission_field_, 01266 // surface_refl_coeffs_field_), 01267 // INPUT( surface_emissivity_field_, f_grid_, stokes_dim_, atmosphere_dim_, p_grid_, 01268 // lat_grid_, lon_grid_, r_geoid_,z_surface_, t_field_, surface_fastem_constants_, 01269 // surface_wind_field_, surface_temperature_), 01270 // GOUTPUT( ), 01271 // GINPUT( ), 01272 // KEYWORDS( ), 01273 // TYPES( ))); 01274 01275 // md_data_raw.push_back 01276 // ( MdRecord 01277 // ( NAME("surfaceNoScatteringSingleEmissivity"), 01278 // DESCRIPTION 01279 // ( 01280 // "Treats the surface to not cause any scattering, and to have a\n" 01281 // "reflection coefficient of 1-e. \n" 01282 // "\n" 01283 // "The size of *surface_emission* is set to [ nf, stokes_dim ] where \n" 01284 // "nf is the length of *f_grid*. Columns 2-4 are set to zero.\n" 01285 // "The temperature of the surface is obtained by interpolating \n" 01286 // "*t_field* to the position of the surface reflection. The obtained \n" 01287 // "temperature and *f_grid* are then used as input to the Planck\n" 01288 // "function. The emission from the surface is then calculated as eB,\n" 01289 // "where B is the Planck function.\n" 01290 // "\n" 01291 // "It is here assumed that the downwelling radiation to consider\n" 01292 // "comes from a single direction and the returned *surface_los*\n" 01293 // "contains only one LOS. The slope of the surface is considered\n" 01294 // "when calculating the LOS for the downwelling radiation. The\n" 01295 // "reflection matrices in *surface_refl_coeffs* are all set to be\n" 01296 // "diagonal matrices, where all diagonal elements are 1-e.\n" 01297 // "\n" 01298 // "Keywords: \n" 01299 // " e : Surface emissivity. Must be a value in the range [0,1].\n" 01300 // " All frequencies are assumed to have the same e." 01301 // ), 01302 // OUTPUT( surface_emission_, surface_los_, surface_refl_coeffs_ ), 01303 // INPUT( f_grid_, stokes_dim_, rte_gp_p_, rte_gp_lat_, rte_gp_lon_, 01304 // rte_los_, atmosphere_dim_, p_grid_, lat_grid_, lon_grid_, 01305 // r_geoid_,z_surface_, t_field_ ), 01306 // GOUTPUT( ), 01307 // GINPUT( ), 01308 // KEYWORDS( "e" ), 01309 // TYPES( Numeric_t ))); 01310 01311 // md_data_raw.push_back 01312 // ( MdRecord 01313 // ( NAME("surfaceTreatAsBlackbody"), 01314 // DESCRIPTION 01315 // ( 01316 // "Sets the surface variables (see below) to model a blackbdoy surface.\n" 01317 // "\n" 01318 // "The function creates the variables *surface_emission*, *surface_los*\n" 01319 // "and *surface_refl_coeffs*. When the surface is treated to act as a\n" 01320 // "blackbody, no downwelling radiation needs to be calculated and\n" 01321 // "*surface_los* and *surface_refl_coeffs* are set to be empty.\n" 01322 // "\n" 01323 // "The size of *surface_emission* is set to [ nf, stokes_dim ] where \n" 01324 // "nf is the length of *f_grid*. Columns 2-4 are set to zero.\n" 01325 // "\n" 01326 // "The temperature of the surface is obtained by interpolating \n" 01327 // "*t_field* to the position of the surface reflection. The obtained \n" 01328 // "temperature and *f_grid* are then used as input to the Planck\n" 01329 // "function and the calculated blackbody radiation is put into the\n" 01330 // "first column of *surface_emission*.\n" 01331 // "\n" 01332 // "Note that this function does not use *rte_los*, *r_geoid* and\n" 01333 // "*z_surface* as input, and if used inside *surface_agenda*,\n" 01334 // "ignore commands for those variables must be added to the agenda." 01335 // ), 01336 // OUTPUT( surface_emission_, surface_los_, surface_refl_coeffs_ ), 01337 // INPUT( f_grid_, stokes_dim_, rte_gp_p_, rte_gp_lat_, rte_gp_lon_, 01338 // atmosphere_dim_, p_grid_, lat_grid_, lon_grid_, t_field_ ), 01339 // GOUTPUT( ), 01340 // GINPUT( ), 01341 // KEYWORDS( ), 01342 // TYPES( ))); 01343 01344 01345