- Timestamp:
- May 13, 2019 11:04:01 AM (6 years ago)
- Location:
- palm/trunk/SOURCE
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/chem_emissions_mod.f90
r3885 r3968 27 27 ! ----------------- 28 28 ! $Id$ 29 ! - in subroutine chem_emissions_match replace all decision structures relating to 30 ! mode_emis to emiss_lod 31 ! - in subroutine chem_check_parameters replace emt%nspec with emt%n_emiss_species 32 ! - spring cleaning (E.C. Chan) 33 ! 34 ! 3885 2019-04-11 11:29:34Z kanani 29 35 ! Changes related to global restructuring of location messages and introduction 30 36 ! of additional debug messages … … 36 42 ! Removed unused variables from chem_emissions_mod 37 43 ! 38 ! 3772 2019-02-28 15:51:57Z suehring44 ! 3772 2019-02-28 15:51:57Z suehring 39 45 ! - In case of parametrized emissions, assure that emissions are only on natural 40 46 ! surfaces (i.e. streets) and not on urban surfaces. 41 47 ! - some unnecessary if clauses removed 42 48 ! 43 ! 3685 2019 -01-21 01:02:11Z knoop49 ! 3685 2019 -01-21 01:02:11Z knoop 44 50 ! Some interface calls moved to module_interface + cleanup 45 51 ! … … 172 178 REAL(wp), PARAMETER :: r_cp = 0.286_wp !< R / cp (exponent for potential temperature) 173 179 174 175 180 SAVE 176 177 181 178 182 ! … … 196 200 MODULE PROCEDURE chem_emissions_setup 197 201 END INTERFACE chem_emissions_setup 198 199 200 202 201 203 PUBLIC chem_emissions_init, chem_emissions_match, chem_emissions_setup … … 213 215 SUBROUTINE chem_emissions_check_parameters 214 216 215 216 217 IMPLICIT NONE 217 218 218 219 TYPE(chem_emis_att_type) :: emt 219 220 220 ! 221 !-- Check Emission Species Number equal to number of passed names for the chemistry species: 222 IF ( SIZE(emt%species_name) /= emt%nspec ) THEN 221 ! 222 !-- Check if species count matches the number of names 223 !-- passed for the chemiscal species 224 225 IF ( SIZE(emt%species_name) /= emt%n_emiss_species ) THEN 226 ! IF ( SIZE(emt%species_name) /= emt%nspec ) THEN 223 227 224 228 message_string = 'Numbers of input emission species names and number of species' // & … … 227 231 228 232 ENDIF 229 230 233 231 234 END SUBROUTINE chem_emissions_check_parameters 235 232 236 233 237 !------------------------------------------------------------------------------! 234 238 ! Description: 235 239 ! ------------ 236 !> Matching the chemical species indices. The routine checks what are the indices of the emission input species 237 !> and the corresponding ones of the model species. The routine gives as output a vector containing the number 238 !> of common species: it is important to note that while the model species are distinct, their values could be 239 !> given to a single species in input: for example, in the case of NO2 and NO, values may be passed in input as 240 !> NOx values. 240 !> Matching the chemical species indices. The routine checks what are the 241 !> indices of the emission input species and the corresponding ones of the 242 !> model species. The routine gives as output a vector containing the number 243 !> of common species: it is important to note that while the model species 244 !> are distinct, their values could be given to a single species in input. 245 !> For example, in the case of NO2 and NO, values may be passed in input as 246 !> NOX values. 241 247 !------------------------------------------------------------------------------! 248 242 249 SUBROUTINE chem_emissions_match( emt_att,len_index ) 243 250 244 251 245 INTEGER(iwp), INTENT(INOUT) :: len_index !< Variable where to store the number of common species between the input dataset and the model species 246 247 TYPE(chem_emis_att_type), INTENT(INOUT) :: emt_att !< Chemistry Emission Array containing information for all the input chemical emission species 248 249 INTEGER(iwp) :: ind_mod, ind_inp !< Parameters for cycling through chemical model and input species 250 INTEGER(iwp) :: nspec_emis_inp !< Variable where to store the number of the emission species in input 251 INTEGER(iwp) :: ind_voc !< Indices to check whether a split for voc should be done 252 INTEGER(iwp) :: ispec !< index for cycle over effective number of emission species 253 254 255 IF ( debug_output ) CALL debug_message( 'chem_emissions_match', 'start' ) 256 257 ! 258 !-- Number of input emission species. 259 nspec_emis_inp=emt_att%nspec 260 261 ! 262 !-- Check the emission mode: DEFAULT, PRE-PROCESSED or PARAMETERIZED 263 SELECT CASE( TRIM( mode_emis ) ) 264 265 ! 266 !-- PRE-PROCESSED mode 267 CASE ( "PRE-PROCESSED" ) 252 253 INTEGER(iwp) :: ind_inp !< Parameters for cycling through chemical input species 254 INTEGER(iwp) :: ind_mod !< Parameters for cycling through chemical model species 255 INTEGER(iwp) :: ind_voc !< Indices to check whether a split for voc should be done 256 INTEGER(iwp) :: ispec !< index for cycle over effective number of emission species 257 INTEGER(iwp) :: nspec_emis_inp !< Variable where to store # of emission species in input 258 259 INTEGER(iwp), INTENT(INOUT) :: len_index !< number of common species between input dataset & model species 260 261 TYPE(chem_emis_att_type), INTENT(INOUT) :: emt_att !< Chemistry Emission Array (decl. netcdf_data_input.f90) 262 263 264 IF ( debug_output ) CALL debug_message( 'chem_emissions_match', 'start' ) 265 266 ! 267 !-- Number of input emission species 268 269 nspec_emis_inp = emt_att%n_emiss_species 270 ! nspec_emis_inp=emt_att%nspec 271 272 ! 273 !-- Check the emission LOD: 0 (PARAMETERIZED), 1 (DEFAULT), 2 (PRE-PROCESSED) 274 ! 275 SELECT CASE (emiss_lod) 276 277 ! 278 !-- LOD 0 (PARAMETERIZED mode) 279 280 CASE (0) 268 281 269 282 len_index = 0 270 len_index_voc = 0 271 272 IF ( nvar > 0 .AND. (nspec_emis_inp > 0) ) THEN 273 ! 274 !-- Cycle over model species 275 DO ind_mod = 1, nvar 276 ! 277 !-- Cycle over input species 278 DO ind_inp = 1, nspec_emis_inp 279 280 ! 281 !-- Check for VOC Species 282 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" ) THEN 283 DO ind_voc = 1, emt_att%nvoc 284 285 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 286 len_index = len_index + 1 287 len_index_voc = len_index_voc + 1 288 ENDIF 289 END DO 290 ENDIF 291 ! 292 !-- Other Species 293 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 294 len_index = len_index + 1 295 ENDIF 296 ENDDO 297 ENDDO 298 299 ! 300 !-- Allocate array for storing the indices of the matched species 301 IF ( len_index > 0 ) THEN 302 303 ALLOCATE( match_spec_input(len_index) ) 304 305 ALLOCATE( match_spec_model(len_index) ) 306 307 IF ( len_index_voc > 0 ) THEN 308 ! 309 !-- contains indices of the VOC model species 310 ALLOCATE( match_spec_voc_model(len_index_voc) ) 311 ! 312 !-- contains the indices of different values of VOC composition of input variable VOC_composition 313 ALLOCATE( match_spec_voc_input(len_index_voc) ) 314 315 ENDIF 316 317 ! 318 !-- pass the species indices to declared arrays 319 len_index = 0 320 321 ! 322 !-- Cycle over model species 323 DO ind_mod = 1, nvar 324 ! 325 !-- Cycle over Input species 326 DO ind_inp = 1, nspec_emis_inp 327 ! 328 !-- VOCs 329 IF ( TRIM(emt_att%species_name(ind_inp) ) == "VOC" .AND. & 330 ALLOCATED(match_spec_voc_input) ) THEN 331 332 DO ind_voc= 1, emt_att%nvoc 333 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 334 len_index = len_index + 1 335 len_index_voc = len_index_voc + 1 336 337 match_spec_input(len_index) = ind_inp 338 match_spec_model(len_index) = ind_mod 339 340 match_spec_voc_input(len_index_voc) = ind_voc 341 match_spec_voc_model(len_index_voc) = ind_mod 342 ENDIF 343 END DO 344 ENDIF 345 346 ! 347 !-- Other Species 348 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 349 len_index = len_index + 1 350 match_spec_input(len_index) = ind_inp 351 match_spec_model(len_index) = ind_mod 352 ENDIF 353 END DO 354 END DO 355 356 ELSE 357 ! 358 !-- in case there are no species matching 359 message_string = 'Non of given emission species' // & 360 ' matches' // & 361 ' model chemical species:' // & 362 ' Emission routine is not called' 363 CALL message( 'chem_emissions_matching', 'CM0438', 0, 0, 0, 6, 0 ) 364 ENDIF 365 366 ELSE 367 368 ! 369 !-- either spc_names is zero or nspec_emis_inp is not allocated 370 message_string = 'Array of Emission species not allocated:' // & 371 ' Either no emission species are provided as input or' // & 372 ' no chemical species are used by PALM:' // & 373 ' Emission routine is not called' 374 CALL message( 'chem_emissions_matching', 'CM0439', 0, 2, 0, 6, 0 ) 375 376 ENDIF 377 378 ! 379 !-- DEFAULT mode 380 CASE ("DEFAULT") 381 382 len_index = 0 !< index for TOTAL number of species 383 len_index_voc = 0 !< index for TOTAL number of VOCs 384 len_index_pm = 3 !< index for TOTAL number of PMs: PM1, PM2.5, PM10. 385 386 IF ( nvar > 0 .AND. nspec_emis_inp > 0 ) THEN 387 388 ! 389 !-- Cycle over model species 390 DO ind_mod = 1, nvar 391 ! 392 !-- Cycle over input species 393 DO ind_inp = 1, nspec_emis_inp 394 395 ! 396 !-- Check for VOC Species 397 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" ) THEN 398 DO ind_voc= 1, emt_att%nvoc 399 400 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 401 len_index = len_index + 1 402 len_index_voc = len_index_voc + 1 403 ENDIF 404 405 END DO 406 ENDIF 407 408 ! 409 !-- PMs: There is one input species name for all PM 410 !-- This variable has 3 dimensions, one for PM1, PM2.5 and PM10 411 IF ( TRIM( emt_att%species_name(ind_inp) ) == "PM" ) THEN 412 ! 413 !-- PM1 414 IF ( TRIM( spc_names(ind_mod) ) == "PM1" ) THEN 415 len_index = len_index + 1 416 ! 417 !-- PM2.5 418 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM25" ) THEN 419 len_index = len_index + 1 420 ! 421 !-- PM10 422 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM10" ) THEN 423 len_index = len_index + 1 424 ENDIF 425 ENDIF 426 427 ! 428 !-- NOx: NO2 and NO 429 IF ( TRIM( emt_att%species_name(ind_inp) ) == "NOx" ) THEN 430 ! 431 !-- NO 432 IF ( TRIM( spc_names(ind_mod) ) == "NO" ) THEN 433 len_index = len_index + 1 434 ! 435 !-- NO2 436 ELSEIF ( TRIM( spc_names(ind_mod) ) == "NO2" ) THEN 437 len_index = len_index + 1 438 ENDIF 439 ENDIF 440 441 ! 442 !-- SOx: SO2 and SO4 443 IF ( TRIM( emt_att%species_name(ind_inp) ) == "SOx" ) THEN 444 ! 445 !-- SO2 446 IF ( TRIM( spc_names(ind_mod) ) == "SO2" ) THEN 447 len_index = len_index + 1 448 ! 449 !-- SO4 450 ELSEIF ( TRIM( spc_names(ind_mod) ) == "SO4" ) THEN 451 len_index = len_index + 1 452 ENDIF 453 ENDIF 454 455 ! 456 !-- Other Species 457 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 458 len_index = len_index + 1 459 ENDIF 460 END DO 461 END DO 462 463 464 ! 465 !-- Allocate arrays 466 IF ( len_index > 0 ) THEN 467 468 ALLOCATE( match_spec_input(len_index) ) 469 ALLOCATE( match_spec_model(len_index) ) 470 471 IF ( len_index_voc > 0 ) THEN 472 ! 473 !-- Contains indices of the VOC model species 474 ALLOCATE( match_spec_voc_model(len_index_voc) ) 475 ! 476 !-- Contains the indices of different values of VOC composition 477 !-- of input variable VOC_composition 478 ALLOCATE( match_spec_voc_input(len_index_voc) ) 479 ENDIF 480 481 ! 482 !-- Pass the species indices to declared arrays 483 len_index = 0 484 len_index_voc = 0 485 486 DO ind_mod = 1, nvar 487 DO ind_inp = 1, nspec_emis_inp 488 489 ! 490 !-- VOCs 491 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" .AND. & 492 ALLOCATED(match_spec_voc_input) ) THEN 493 DO ind_voc= 1, emt_att%nvoc 494 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 495 len_index = len_index + 1 496 len_index_voc = len_index_voc + 1 497 498 match_spec_input(len_index) = ind_inp 499 match_spec_model(len_index) = ind_mod 500 501 match_spec_voc_input(len_index_voc) = ind_voc 502 match_spec_voc_model(len_index_voc) = ind_mod 503 ENDIF 504 END DO 505 ENDIF 506 507 ! 508 !-- PMs 509 IF ( TRIM( emt_att%species_name(ind_inp) ) == "PM" ) THEN 510 ! 511 !-- PM1 512 IF ( TRIM( spc_names(ind_mod) ) == "PM1" ) THEN 513 len_index = len_index + 1 514 515 match_spec_input(len_index) = ind_inp 516 match_spec_model(len_index) = ind_mod 517 ! 518 !-- PM2.5 519 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM25" ) THEN 520 len_index = len_index + 1 521 522 match_spec_input(len_index) = ind_inp 523 match_spec_model(len_index) = ind_mod 524 ! 525 !-- PM10 526 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM10" ) THEN 527 len_index = len_index + 1 528 529 match_spec_input(len_index) = ind_inp 530 match_spec_model(len_index) = ind_mod 531 532 ENDIF 533 ENDIF 534 535 ! 536 !-- NOx 537 IF ( TRIM( emt_att%species_name(ind_inp) ) == "NOx" ) THEN 538 ! 539 !-- NO 540 IF ( TRIM( spc_names(ind_mod) ) == "NO" ) THEN 541 len_index = len_index + 1 542 543 match_spec_input(len_index) = ind_inp 544 match_spec_model(len_index) = ind_mod 545 ! 546 !-- NO2 547 ELSEIF ( TRIM( spc_names(ind_mod) ) == "NO2" ) THEN 548 len_index = len_index + 1 549 550 match_spec_input(len_index) = ind_inp 551 match_spec_model(len_index) = ind_mod 552 553 ENDIF 554 ENDIF 555 556 ! 557 !-- SOx 558 IF ( TRIM( emt_att%species_name(ind_inp) ) == "SOx" ) THEN 559 ! 560 !-- SO2 561 IF ( TRIM( spc_names(ind_mod) ) == "SO2" ) THEN 562 len_index = len_index + 1 563 564 match_spec_input(len_index) = ind_inp 565 match_spec_model(len_index) = ind_mod 566 567 ! 568 !-- SO4 569 ELSEIF ( TRIM( spc_names(ind_mod) ) == "SO4" ) THEN 570 len_index = len_index + 1 571 572 match_spec_input(len_index) = ind_inp 573 match_spec_model(len_index) = ind_mod 574 575 ENDIF 576 ENDIF 577 578 ! 579 !-- Other Species 580 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 581 len_index = len_index + 1 582 583 match_spec_input(len_index) = ind_inp 584 match_spec_model(len_index) = ind_mod 585 ENDIF 586 END DO 587 END DO 588 589 ELSE 590 591 message_string = 'Non of given Emission Species' // & 592 ' matches' // & 593 ' model chemical species' // & 594 ' Emission routine is not called' 595 CALL message( 'chem_emissions_matching', 'CM0440', 0, 0, 0, 6, 0 ) 596 597 ENDIF 598 599 ELSE 600 601 message_string = 'Array of Emission species not allocated: ' // & 602 ' Either no emission species are provided as input or' // & 603 ' no chemical species are used by PALM:' // & 604 ' Emission routine is not called' 605 CALL message( 'chem_emissions_matching', 'CM0441', 0, 2, 0, 6, 0 ) 606 607 ENDIF 608 609 ! 610 !-- PARAMETERIZED mode 611 CASE ("PARAMETERIZED") 612 613 len_index = 0 614 615 IF ( nvar > 0 .AND. nspec_emis_inp > 0 ) THEN 616 617 ! 618 !-- Cycle over model species 283 284 IF ( nvar > 0 .AND. nspec_emis_inp > 0 ) THEN 285 286 ! 287 !-- Cycle over model species 288 619 289 DO ind_mod = 1, nvar 620 290 ind_inp = 1 621 291 DO WHILE ( TRIM( surface_csflux_name(ind_inp) ) /= 'novalue' ) !< 'novalue' is the default 622 IF ( TRIM( surface_csflux_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN292 IF ( TRIM( surface_csflux_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 623 293 len_index = len_index + 1 624 294 ENDIF … … 627 297 ENDDO 628 298 629 IF ( len_index > 0 ) THEN 630 631 ! 632 !-- Allocation of Arrays of the matched species 633 ALLOCATE( match_spec_input(len_index) ) 634 635 ALLOCATE( match_spec_model(len_index) ) 636 637 ! 638 !-- Pass the species indices to declared arrays 299 IF ( len_index > 0 ) THEN 300 301 ! 302 !-- Allocation of Arrays of the matched species 303 304 ALLOCATE ( match_spec_input(len_index) ) 305 ALLOCATE ( match_spec_model(len_index) ) 306 307 ! 308 !-- Pass species indices to declared arrays 309 639 310 len_index = 0 640 311 641 312 DO ind_mod = 1, nvar 642 313 ind_inp = 1 643 DO WHILE ( TRIM( surface_csflux_name(ind_inp) ) /= 'novalue' ) 644 IF ( TRIM( surface_csflux_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 314 DO WHILE ( TRIM( surface_csflux_name(ind_inp) ) /= 'novalue' ) 315 IF ( TRIM(surface_csflux_name(ind_inp)) == & 316 TRIM(spc_names(ind_mod)) ) THEN 645 317 len_index = len_index + 1 646 318 match_spec_input(len_index) = ind_inp … … 651 323 END DO 652 324 653 ! 654 !-- Check 325 ! 326 !-- Check 327 655 328 DO ispec = 1, len_index 656 329 657 IF ( emiss_factor_main(match_spec_input(ispec) ) < 0 .AND. &330 IF ( emiss_factor_main(match_spec_input(ispec) ) < 0 .AND. & 658 331 emiss_factor_side(match_spec_input(ispec) ) < 0 ) THEN 659 332 660 message_string = 'PARAMETERIZED emissions mode selected:' //&333 message_string = 'PARAMETERIZED emissions mode selected:' // & 661 334 ' EMISSIONS POSSIBLE ONLY ON STREET SURFACES' // & 662 335 ' but values of scaling factors for street types' // & … … 665 338 ' or not provided at all: PLEASE set a finite value' // & 666 339 ' for these parameters in the chemistry namelist' 667 CALL message( 'chem_emissions_matching', 'CM0442', 2, 2, 0, 6, 0 ) 340 CALL message( 'chem_emissions_matching', 'CM0442', 2, 2, 0, 6, 0 ) 341 668 342 ENDIF 343 669 344 END DO 670 345 … … 672 347 ELSE 673 348 674 message_string = 'Non of given Emission Species' //&349 message_string = 'Non of given Emission Species' // & 675 350 ' matches' // & 676 351 ' model chemical species' // & 677 352 ' Emission routine is not called' 678 CALL message( 'chem_emissions_matching', 'CM0443', 0, 0, 0, 6, 0 ) 353 CALL message( 'chem_emissions_matching', 'CM0443', 0, 0, 0, 6, 0 ) 354 679 355 ENDIF 680 356 681 357 ELSE 682 358 683 message_string = 'Array of Emission species not allocated: ' //&359 message_string = 'Array of Emission species not allocated: ' // & 684 360 ' Either no emission species are provided as input or' // & 685 361 ' no chemical species are used by PALM.' // & … … 687 363 CALL message( 'chem_emissions_matching', 'CM0444', 0, 2, 0, 6, 0 ) 688 364 689 ENDIF 690 691 692 ! 693 !-- If emission module is switched on but mode_emis is not specified or it is given the wrong name 365 ENDIF 366 367 ! 368 !-- LOD 1 (DEFAULT mode) 369 370 CASE (1) 371 372 len_index = 0 ! TOTAL number of species (to be accumulated) 373 len_index_voc = 0 ! TOTAL number of VOCs (to be accumulated) 374 len_index_pm = 3 ! TOTAL number of PMs: PM1, PM2.5, PM10. 375 376 IF ( nvar > 0 .AND. nspec_emis_inp > 0 ) THEN 377 378 ! 379 !-- Cycle over model species 380 DO ind_mod = 1, nvar 381 382 ! 383 !-- Cycle over input species 384 385 DO ind_inp = 1, nspec_emis_inp 386 387 ! 388 !-- Check for VOC Species 389 390 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" ) THEN 391 DO ind_voc= 1, emt_att%nvoc 392 393 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 394 len_index = len_index + 1 395 len_index_voc = len_index_voc + 1 396 ENDIF 397 398 END DO 399 ENDIF 400 401 ! 402 !-- PMs: There is one input species name for all PM 403 !-- This variable has 3 dimensions, one for PM1, PM2.5 and PM10 404 405 IF ( TRIM( emt_att%species_name(ind_inp) ) == "PM" ) THEN 406 407 IF ( TRIM( spc_names(ind_mod) ) == "PM1" ) THEN 408 len_index = len_index + 1 409 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM25" ) THEN 410 len_index = len_index + 1 411 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM10" ) THEN 412 len_index = len_index + 1 413 ENDIF 414 415 ENDIF 416 417 ! 418 !-- NOX: NO2 and NO 419 420 IF ( TRIM( emt_att%species_name(ind_inp) ) == "NOX" ) THEN 421 422 IF ( TRIM( spc_names(ind_mod) ) == "NO" ) THEN 423 len_index = len_index + 1 424 ELSEIF ( TRIM( spc_names(ind_mod) ) == "NO2" ) THEN 425 len_index = len_index + 1 426 ENDIF 427 428 ENDIF 429 430 ! 431 !-- SOX: SO2 and SO4 432 433 IF ( TRIM( emt_att%species_name(ind_inp) ) == "SOX" ) THEN 434 435 IF ( TRIM( spc_names(ind_mod) ) == "SO2" ) THEN 436 len_index = len_index + 1 437 ELSEIF ( TRIM( spc_names(ind_mod) ) == "SO4" ) THEN 438 len_index = len_index + 1 439 ENDIF 440 441 ENDIF 442 443 ! 444 !-- Other Species 445 446 IF ( TRIM( emt_att%species_name(ind_inp) ) == & 447 TRIM( spc_names(ind_mod) ) ) THEN 448 len_index = len_index + 1 449 ENDIF 450 451 END DO ! ind_inp ... 452 453 END DO ! ind_mod ... 454 455 456 ! 457 !-- Allocate arrays 458 459 IF ( len_index > 0 ) THEN 460 461 ALLOCATE ( match_spec_input(len_index) ) 462 ALLOCATE ( match_spec_model(len_index) ) 463 464 IF ( len_index_voc > 0 ) THEN 465 466 ! 467 !-- Contains indices of the VOC model species 468 469 ALLOCATE( match_spec_voc_model(len_index_voc) ) 470 471 ! 472 !-- Contains the indices of different values of VOC composition 473 !-- of input variable VOC_composition 474 475 ALLOCATE( match_spec_voc_input(len_index_voc) ) 476 477 ENDIF 478 479 ! 480 !-- Pass the species indices to declared arrays 481 482 len_index = 0 483 len_index_voc = 0 484 485 DO ind_mod = 1, nvar 486 DO ind_inp = 1, nspec_emis_inp 487 488 ! 489 !-- VOCs 490 491 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" .AND. & 492 ALLOCATED (match_spec_voc_input) ) THEN 493 494 DO ind_voc = 1, emt_att%nvoc 495 496 IF ( TRIM( emt_att%voc_name(ind_voc) ) == & 497 TRIM( spc_names(ind_mod) ) ) THEN 498 499 len_index = len_index + 1 500 len_index_voc = len_index_voc + 1 501 502 match_spec_input(len_index) = ind_inp 503 match_spec_model(len_index) = ind_mod 504 505 match_spec_voc_input(len_index_voc) = ind_voc 506 match_spec_voc_model(len_index_voc) = ind_mod 507 508 ENDIF 509 510 END DO 511 512 ENDIF 513 514 ! 515 !-- PMs 516 517 IF ( TRIM( emt_att%species_name(ind_inp) ) == "PM" ) THEN 518 519 IF ( TRIM( spc_names(ind_mod) ) == "PM1" ) THEN 520 len_index = len_index + 1 521 match_spec_input(len_index) = ind_inp 522 match_spec_model(len_index) = ind_mod 523 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM25" ) THEN 524 len_index = len_index + 1 525 match_spec_input(len_index) = ind_inp 526 match_spec_model(len_index) = ind_mod 527 ELSEIF ( TRIM( spc_names(ind_mod) ) == "PM10" ) THEN 528 len_index = len_index + 1 529 match_spec_input(len_index) = ind_inp 530 match_spec_model(len_index) = ind_mod 531 ENDIF 532 533 ENDIF 534 535 ! 536 !-- NOX 537 IF ( TRIM( emt_att%species_name(ind_inp) ) == "NOX" ) THEN 538 539 IF ( TRIM( spc_names(ind_mod) ) == "NO" ) THEN 540 len_index = len_index + 1 541 542 match_spec_input(len_index) = ind_inp 543 match_spec_model(len_index) = ind_mod 544 545 ELSEIF ( TRIM( spc_names(ind_mod) ) == "NO2" ) THEN 546 len_index = len_index + 1 547 548 match_spec_input(len_index) = ind_inp 549 match_spec_model(len_index) = ind_mod 550 551 ENDIF 552 553 ENDIF 554 555 556 ! 557 !-- SOX 558 559 IF ( TRIM( emt_att%species_name(ind_inp) ) == "SOX" ) THEN 560 561 IF ( TRIM( spc_names(ind_mod) ) == "SO2" ) THEN 562 len_index = len_index + 1 563 match_spec_input(len_index) = ind_inp 564 match_spec_model(len_index) = ind_mod 565 ELSEIF ( TRIM( spc_names(ind_mod) ) == "SO4" ) THEN 566 len_index = len_index + 1 567 match_spec_input(len_index) = ind_inp 568 match_spec_model(len_index) = ind_mod 569 ENDIF 570 571 ENDIF 572 573 ! 574 !-- Other Species 575 576 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 577 len_index = len_index + 1 578 match_spec_input(len_index) = ind_inp 579 match_spec_model(len_index) = ind_mod 580 ENDIF 581 582 END DO ! inp_ind 583 584 END DO ! inp_mod 585 586 ! 587 !-- Error reporting (no matching) 588 589 ELSE 590 591 message_string = 'None of given Emission Species matches' // & 592 ' model chemical species' // & 593 ' Emission routine is not called' 594 CALL message( 'chem_emissions_matching', 'CM0440', 0, 0, 0, 6, 0 ) 595 596 ENDIF 597 598 ! 599 !-- Error reporting (no species) 600 601 ELSE 602 603 message_string = 'Array of Emission species not allocated: ' // & 604 ' Either no emission species are provided as input or' // & 605 ' no chemical species are used by PALM:' // & 606 ' Emission routine is not called' 607 CALL message( 'chem_emissions_matching', 'CM0441', 0, 2, 0, 6, 0 ) 608 609 ENDIF 610 611 ! 612 !-- LOD 2 (PRE-PROCESSED mode) 613 614 CASE (2) 615 616 len_index = 0 617 len_index_voc = 0 618 619 IF ( nvar > 0 .AND. (nspec_emis_inp > 0) ) THEN 620 ! 621 !-- Cycle over model species 622 DO ind_mod = 1, nvar 623 624 ! 625 !-- Cycle over input species 626 DO ind_inp = 1, nspec_emis_inp 627 628 ! 629 !-- Check for VOC Species 630 631 IF ( TRIM( emt_att%species_name(ind_inp) ) == "VOC" ) THEN 632 DO ind_voc = 1, emt_att%nvoc 633 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 634 len_index = len_index + 1 635 len_index_voc = len_index_voc + 1 636 ENDIF 637 END DO 638 ENDIF 639 640 ! 641 !-- Other Species 642 643 IF ( TRIM(emt_att%species_name(ind_inp)) == TRIM(spc_names(ind_mod)) ) THEN 644 len_index = len_index + 1 645 ENDIF 646 ENDDO 647 ENDDO 648 649 ! 650 !-- Allocate array for storing the indices of the matched species 651 652 IF ( len_index > 0 ) THEN 653 654 ALLOCATE ( match_spec_input(len_index) ) 655 656 ALLOCATE ( match_spec_model(len_index) ) 657 658 IF ( len_index_voc > 0 ) THEN 659 ! 660 !-- contains indices of the VOC model species 661 ALLOCATE( match_spec_voc_model(len_index_voc) ) 662 ! 663 !-- contains the indices of different values of VOC composition of input variable VOC_composition 664 ALLOCATE( match_spec_voc_input(len_index_voc) ) 665 666 ENDIF 667 668 ! 669 !-- pass the species indices to declared arrays 670 671 len_index = 0 672 673 ! 674 !-- Cycle over model species 675 676 DO ind_mod = 1, nvar 677 678 ! 679 !-- Cycle over Input species 680 681 DO ind_inp = 1, nspec_emis_inp 682 683 ! 684 !-- VOCs 685 686 IF ( TRIM(emt_att%species_name(ind_inp) ) == "VOC" .AND. & 687 ALLOCATED(match_spec_voc_input) ) THEN 688 689 DO ind_voc= 1, emt_att%nvoc 690 IF ( TRIM( emt_att%voc_name(ind_voc) ) == TRIM( spc_names(ind_mod) ) ) THEN 691 len_index = len_index + 1 692 len_index_voc = len_index_voc + 1 693 694 match_spec_input(len_index) = ind_inp 695 match_spec_model(len_index) = ind_mod 696 697 match_spec_voc_input(len_index_voc) = ind_voc 698 match_spec_voc_model(len_index_voc) = ind_mod 699 ENDIF 700 END DO 701 ENDIF 702 703 ! 704 !-- Other Species 705 706 IF ( TRIM( emt_att%species_name(ind_inp) ) == TRIM( spc_names(ind_mod) ) ) THEN 707 len_index = len_index + 1 708 match_spec_input(len_index) = ind_inp 709 match_spec_model(len_index) = ind_mod 710 ENDIF 711 712 END DO ! ind_inp 713 END DO ! ind_mod 714 715 ELSE ! if len_index_voc .le. 0 716 717 ! 718 !-- in case there are no species matching 719 720 message_string = 'Non of given emission species' // & 721 ' matches' // & 722 ' model chemical species:' // & 723 ' Emission routine is not called' 724 CALL message( 'chem_emissions_matching', 'CM0438', 0, 0, 0, 6, 0 ) 725 ENDIF 726 727 ! 728 !-- Error check (no matching) 729 730 ELSE 731 732 ! 733 !-- either spc_names is zero or nspec_emis_inp is not allocated 734 message_string = 'Array of Emission species not allocated:' // & 735 ' Either no emission species are provided as input or' // & 736 ' no chemical species are used by PALM:' // & 737 ' Emission routine is not called' 738 CALL message( 'chem_emissions_matching', 'CM0439', 0, 2, 0, 6, 0 ) 739 740 ENDIF 741 742 ! 743 !-- If emission module is switched on but mode_emis is not specified or it is given the wrong name 744 745 ! 746 !-- Error check (no species) 747 694 748 CASE DEFAULT 695 749 696 message_string = 'Emission Module switched ON, but' //&697 ' either no emission mode specified or incorrectly given :' // 750 message_string = 'Emission Module switched ON, but' // & 751 ' either no emission mode specified or incorrectly given :' // & 698 752 ' please, pass the correct value to the namelist parameter "mode_emis"' 699 753 CALL message( 'chem_emissions_matching', 'CM0445', 2, 2, 0, 6, 0 ) … … 701 755 END SELECT 702 756 703 IF ( debug_output ) CALL debug_message( 'chem_emissions_match', 'end' )757 IF ( debug_output ) CALL debug_message( 'chem_emissions_match', 'end' ) 704 758 705 759 END SUBROUTINE chem_emissions_match … … 724 778 ! 725 779 !-- Actions for initial runs 726 ! IF ( TRIM( initializing_actions ) /= 'read_restart_data' ) THEN780 ! IF ( TRIM( initializing_actions ) /= 'read_restart_data' ) THEN 727 781 !-- ... 728 782 ! … … 735 789 736 790 737 IF ( debug_output ) CALL debug_message( 'chem_emissions_init', 'start' ) 738 739 ! 740 !-- Matching 741 CALL chem_emissions_match( chem_emis_att, nspec_out ) 742 743 IF ( nspec_out == 0 ) THEN 791 IF ( debug_output ) CALL debug_message( 'chem_emissions_init', 'start' ) 792 793 ! 794 !-- Matching 795 796 CALL chem_emissions_match( chem_emis_att, n_matched_vars ) 797 798 IF ( n_matched_vars == 0 ) THEN 744 799 745 emission_output_required = .FALSE. 746 747 ELSE 748 749 emission_output_required = .TRUE. 750 751 752 ! 753 !-- Set molecule masses' 754 ALLOCATE( chem_emis_att%xm(nspec_out) ) 755 756 DO ispec = 1, nspec_out 757 SELECT CASE ( TRIM( spc_names(match_spec_model(ispec)) ) ) 758 CASE ( 'SO2' ); chem_emis_att%xm(ispec) = xm_S + xm_O * 2 !< kg/mole 759 CASE ( 'SO4' ); chem_emis_att%xm(ispec) = xm_S + xm_O * 4 !< kg/mole 760 CASE ( 'NO' ); chem_emis_att%xm(ispec) = xm_N + xm_O !< kg/mole 761 CASE ( 'NO2' ); chem_emis_att%xm(ispec) = xm_N + xm_O * 2 !< kg/mole 762 CASE ( 'NH3' ); chem_emis_att%xm(ispec) = xm_N + xm_H * 3 !< kg/mole 763 CASE ( 'CO' ); chem_emis_att%xm(ispec) = xm_C + xm_O !< kg/mole 764 CASE ( 'CO2' ); chem_emis_att%xm(ispec) = xm_C + xm_O * 2 !< kg/mole 765 CASE ( 'CH4' ); chem_emis_att%xm(ispec) = xm_C + xm_H * 4 !< kg/mole 766 CASE ( 'HNO3' ); chem_emis_att%xm(ispec) = xm_H + xm_N + xm_O*3 !< kg/mole 767 CASE DEFAULT 768 chem_emis_att%xm(ispec) = 1.0_wp 769 END SELECT 770 ENDDO 800 emission_output_required = .FALSE. 801 802 ELSE 803 804 emission_output_required = .TRUE. 805 806 807 ! 808 !-- Set molecule masses (in kg/mol) 809 810 ALLOCATE( chem_emis_att%xm(n_matched_vars) ) 811 812 DO ispec = 1, n_matched_vars 813 SELECT CASE ( TRIM( spc_names(match_spec_model(ispec)) ) ) 814 CASE ( 'SO2' ); chem_emis_att%xm(ispec) = xm_S + xm_O * 2 815 CASE ( 'SO4' ); chem_emis_att%xm(ispec) = xm_S + xm_O * 4 816 CASE ( 'NO' ); chem_emis_att%xm(ispec) = xm_N + xm_O 817 CASE ( 'NO2' ); chem_emis_att%xm(ispec) = xm_N + xm_O * 2 818 CASE ( 'NH3' ); chem_emis_att%xm(ispec) = xm_N + xm_H * 3 819 CASE ( 'CO' ); chem_emis_att%xm(ispec) = xm_C + xm_O 820 CASE ( 'CO2' ); chem_emis_att%xm(ispec) = xm_C + xm_O * 2 821 CASE ( 'CH4' ); chem_emis_att%xm(ispec) = xm_C + xm_H * 4 822 CASE ( 'HNO3' ); chem_emis_att%xm(ispec) = xm_H + xm_N + xm_O*3 823 CASE DEFAULT 824 chem_emis_att%xm(ispec) = 1.0_wp 825 END SELECT 826 ENDDO 771 827 772 828 773 ! 774 !-- assign emission values 775 SELECT CASE ( TRIM( mode_emis ) ) 776 777 778 ! 779 !-- PRE-PROCESSED case 780 CASE ( "PRE-PROCESSED" ) 781 782 IF ( .NOT. ALLOCATED( emis_distribution) ) ALLOCATE( emis_distribution(nzb:nzt+1,0:ny,0:nx,nspec_out) ) 783 784 ! 785 !-- Get emissions at the first time step 786 CALL chem_emissions_setup( chem_emis_att, chem_emis, nspec_out ) 787 788 ! 789 !-- Default case 790 CASE ( "DEFAULT" ) 791 792 IF ( .NOT. ALLOCATED( emis_distribution) ) ALLOCATE( emis_distribution(1,0:ny,0:nx,nspec_out) ) 793 794 ! 795 !-- Get emissions at the first time step 796 CALL chem_emissions_setup( chem_emis_att, chem_emis, nspec_out ) 797 798 ! 799 !-- PARAMETERIZED case 800 CASE ( "PARAMETERIZED" ) 801 802 IF ( .NOT. ALLOCATED( emis_distribution) ) ALLOCATE( emis_distribution(1,0:ny,0:nx,nspec_out) ) 803 804 ! 805 !-- Get emissions at the first time step 806 CALL chem_emissions_setup( chem_emis_att, chem_emis, nspec_out) 807 808 END SELECT 809 810 ENDIF 811 812 IF ( debug_output ) CALL debug_message( 'chem_emissions_init', 'end' ) 829 ! 830 !-- Get emissions for the first time step base on LOD (if defined) 831 !-- or emission mode (if no LOD defined) 832 833 ! 834 !-- NOTE - I could use a combined if ( lod = xxx .or. mode = 'XXX' ) 835 !-- type of decision structure but I think it is much better 836 !-- to implement it this way (i.e., conditional on lod if it 837 !-- is defined, and mode if not) as we can easily take out 838 !-- the case structure for mode_emis later on. 839 !-- (ecc 20140424) 840 841 IF ( emiss_lod < 0 ) THEN !-- no LOD defined (not likely) 842 843 SELECT CASE ( TRIM( mode_emis ) ) 844 845 CASE ( 'PARAMETERIZED' ) ! LOD 0 846 847 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 848 ALLOCATE( emis_distribution(1,0:ny,0:nx,n_matched_vars) ) 849 ENDIF 850 851 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars) 852 853 CASE ( 'DEFAULT' ) ! LOD 1 854 855 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 856 ALLOCATE( emis_distribution(1,0:ny,0:nx,n_matched_vars) ) 857 ENDIF 858 859 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars ) 860 861 CASE ( 'PRE-PROCESSED' ) ! LOD 2 862 863 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 864 ALLOCATE( emis_distribution(nzb:nzt+1,0:ny,0:nx,n_matched_vars) ) 865 ENDIF 866 867 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars ) 868 869 END SELECT 870 871 ELSE ! if LOD is defined 872 873 SELECT CASE ( emiss_lod ) 874 875 CASE ( 0 ) ! parameterized mode 876 877 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 878 ALLOCATE( emis_distribution(1,0:ny,0:nx,n_matched_vars) ) 879 ENDIF 880 881 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars) 882 883 CASE ( 1 ) ! default mode 884 885 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 886 ALLOCATE( emis_distribution(1,0:ny,0:nx,n_matched_vars) ) 887 ENDIF 888 889 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars ) 890 891 CASE ( 2 ) ! pre-processed mode 892 893 IF ( .NOT. ALLOCATED( emis_distribution) ) THEN 894 ALLOCATE( emis_distribution(nzb:nzt+1,0:ny,0:nx,n_matched_vars) ) 895 ENDIF 896 897 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars ) 898 899 END SELECT 900 901 ENDIF 902 903 ENDIF 904 905 IF ( debug_output ) CALL debug_message( 'chem_emissions_init', 'end' ) 813 906 814 907 END SUBROUTINE chem_emissions_init … … 822 915 !-------------------------------------------------------------------------------! 823 916 824 SUBROUTINE chem_emissions_setup( emt_att, emt, n spec_out)917 SUBROUTINE chem_emissions_setup( emt_att, emt, n_matched_vars ) 825 918 826 919 USE surface_mod, & … … 835 928 836 929 837 TYPE(chem_emis_att_type), INTENT(INOUT) :: emt_att !< variable to store emission information 930 TYPE(chem_emis_att_type), INTENT(INOUT) :: emt_att !< variable to store emission information 838 931 839 932 TYPE(chem_emis_val_type), INTENT(INOUT), ALLOCATABLE, DIMENSION(:) :: emt !< variable to store emission input values, 840 933 !< depending on the considered species 841 934 842 INTEGER,INTENT(IN) :: n spec_out!< Output of matching routine with number935 INTEGER,INTENT(IN) :: n_matched_vars !< Output of matching routine with number 843 936 !< of matched species 844 937 … … 858 951 859 952 REAL(wp), DIMENSION(24) :: par_emis_time_factor !< time factors for the parameterized mode: 860 !< fixed houlry profile for example day861 REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) :: conv_to_ratio !< factor used for converting input953 !< fixed houlry profile for example day 954 REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) :: conv_to_ratio !< factor used for converting input 862 955 !< to concentration ratio 863 956 REAL(wp), DIMENSION(nzb:nzt+1,nys:nyn,nxl:nxr) :: tmp_temp … … 883 976 !------------------------------------------------------ 884 977 885 IF ( emission_output_required ) THEN978 IF ( emission_output_required ) THEN 886 979 887 980 ! 888 981 !-- Set emis_dt 889 IF ( call_chem_at_all_substeps ) THEN982 IF ( call_chem_at_all_substeps ) THEN 890 983 891 984 dt_emis = dt_3d * weight_pres(intermediate_timestep_count) … … 897 990 ENDIF 898 991 899 900 ! 901 !-- Conversion of units to the ones employed in PALM 902 !-- In PARAMETERIZED mode no conversion is performed: in this case input units are fixed 903 904 IF ( TRIM( mode_emis ) == "DEFAULT" .OR. TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN 992 ! 993 !-- Conversion of units to the ones employed in PALM 994 !-- In PARAMETERIZED mode no conversion is performed: in this case input units are fixed 995 996 IF ( TRIM( mode_emis ) == "DEFAULT" .OR. TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN 905 997 906 998 SELECT CASE ( TRIM( emt_att%units ) ) 907 ! 908 !-- kilograms 909 CASE ( 'kg/m2/s', 'KG/M2/S' ) 910 911 con_factor=1 912 913 CASE ('kg/m2/hour', 'KG/M2/HOUR' ) 914 915 con_factor=hour_to_s 916 917 CASE ( 'kg/m2/day', 'KG/M2/DAY' ) 918 919 con_factor=day_to_s 920 921 CASE ( 'kg/m2/year', 'KG/M2/YEAR' ) 922 923 con_factor=year_to_s 924 925 ! 926 !-- Tons 927 CASE ( 'ton/m2/s', 'TON/M2/S' ) 928 929 con_factor=tons_to_kg 930 931 CASE ( 'ton/m2/hour', 'TON/M2/HOUR' ) 932 933 con_factor=tons_to_kg*hour_to_s 934 935 CASE ( 'ton/m2/year', 'TON/M2/YEAR' ) 936 937 con_factor=tons_to_kg*year_to_s 938 939 ! 940 !-- Grams 941 CASE ( 'g/m2/s', 'G/M2/S' ) 942 943 con_factor=g_to_kg 944 945 CASE ( 'g/m2/hour', 'G/M2/HOUR' ) 946 947 con_factor=g_to_kg*hour_to_s 948 949 CASE ( 'g/m2/year', 'G/M2/YEAR' ) 950 951 con_factor=g_to_kg*year_to_s 952 953 ! 954 !-- Micrograms 955 CASE ( 'micrograms/m2/s', 'MICROGRAMS/M2/S' ) 956 957 con_factor=miug_to_kg 958 959 CASE ( 'micrograms/m2/hour', 'MICROGRAMS/M2/HOUR' ) 960 961 con_factor=miug_to_kg*hour_to_s 962 963 CASE ( 'micrograms/m2/year', 'MICROGRAMS/M2/YEAR' ) 964 965 con_factor=miug_to_kg*year_to_s 999 1000 CASE ( 'kg/m2/s', 'KG/M2/S' ); con_factor = 1.0_wp ! kg 1001 CASE ( 'kg/m2/hour', 'KG/M2/HOUR' ); con_factor = hour_to_s 1002 CASE ( 'kg/m2/day', 'KG/M2/DAY' ); con_factor = day_to_s 1003 CASE ( 'kg/m2/year', 'KG/M2/YEAR' ); con_factor = year_to_s 1004 1005 CASE ( 'ton/m2/s', 'TON/M2/S' ); con_factor = tons_to_kg ! tonnes 1006 CASE ( 'ton/m2/hour', 'TON/M2/HOUR' ); con_factor = tons_to_kg*hour_to_s 1007 CASE ( 'ton/m2/year', 'TON/M2/YEAR' ); con_factor = tons_to_kg*year_to_s 1008 1009 CASE ( 'g/m2/s', 'G/M2/S' ); con_factor = g_to_kg ! grams 1010 CASE ( 'g/m2/hour', 'G/M2/HOUR' ); con_factor = g_to_kg*hour_to_s 1011 CASE ( 'g/m2/year', 'G/M2/YEAR' ); con_factor = g_to_kg*year_to_s 1012 1013 CASE ( 'micrograms/m2/s', 'MICROGRAMS/M2/S' ); con_factor = miug_to_kg ! ug 1014 CASE ( 'micrograms/m2/hour', 'MICROGRAMS/M2/HOUR' ); con_factor = miug_to_kg*hour_to_s 1015 CASE ( 'micrograms/m2/year', 'MICROGRAMS/M2/YEAR' ); con_factor = miug_to_kg*year_to_s 1016 1017 ! 1018 !-- Error check (need units) 966 1019 967 1020 CASE DEFAULT 968 message_string = 'The Units of the provided emission input' // &969 ' are not the ones required by PALM-4U: please check ' 1021 message_string = 'The Units of the provided emission input' // & 1022 ' are not the ones required by PALM-4U: please check ' // & 970 1023 ' emission module documentation.' 971 1024 CALL message( 'chem_emissions_setup', 'CM0446', 2, 2, 0, 6, 0 ) … … 973 1026 END SELECT 974 1027 975 976 1028 ENDIF 977 1029 978 ! 979 !-- Conversion factor to convert kg/m**2/s to ppm/s 1030 ! 1031 !-- Conversion factor to convert kg/m**2/s to ppm/s 1032 980 1033 DO i = nxl, nxr 981 1034 DO j = nys, nyn 982 ! 983 !-- Derive Temperature from Potential Temperature 1035 1036 ! 1037 !-- Derive Temperature from Potential Temperature 1038 984 1039 tmp_temp(nzb:nzt+1,j,i) = pt(nzb:nzt+1,j,i) * ( hyp(nzb:nzt+1) * pref_i )**r_cp 985 986 987 !> We need to pass to cssws <- (ppm/s) * dz 988 !> Input is Nmole/(m^2*s) 989 !> To go to ppm*dz multiply the input by (m**2/N)*dz 990 !> (m**2/N)*dz == V/N 991 !> V/N = RT/P 992 !> m**3/Nmole (J/mol)*K^-1 K Pa 1040 1041 ! 1042 !-- We need to pass to cssws <- (ppm/s) * dz 1043 !-- Input is Nmole/(m^2*s) 1044 !-- To go to ppm*dz multiply the input by (m**2/N)*dz 1045 !-- (m**2/N)*dz == V/N 1046 !-- V/N = RT/P 1047 1048 ! m**3/Nmole (J/mol)*K^-1 K Pa 993 1049 conv_to_ratio(nzb:nzt+1,j,i) = ( (Rgas * tmp_temp(nzb:nzt+1,j,i)) / ((hyp(nzb:nzt+1))) ) 1050 994 1051 ENDDO 995 1052 ENDDO 996 1053 997 1054 998 ! 999 !-- Initialize 1055 ! 1056 !-- Initialize 1057 1000 1058 emis_distribution(:,nys:nyn,nxl:nxr,:) = 0.0_wp 1001 1059 1002 1060 1003 ! 1004 !-- PRE-PROCESSED MODE 1005 IF ( TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN 1006 1007 ! 1008 !-- Update time indices 1061 ! 1062 !-- LOD 2 (PRE-PROCESSED MODE) 1063 1064 IF ( emiss_lod == 2 ) THEN 1065 1066 ! for reference (ecc) 1067 ! IF ( TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN 1068 1069 ! 1070 !-- Update time indices 1071 1009 1072 CALL time_preprocessed_indices( index_hh ) 1010 1073 1011 ELSEIF ( TRIM( mode_emis ) == "DEFAULT" ) THEN 1012 1013 ! 1014 !-- Allocate array where to store temporary emission values 1015 IF ( .NOT. ALLOCATED(emis) ) ALLOCATE( emis(nys:nyn,nxl:nxr) ) 1016 ! 1017 !-- Allocate time factor per category 1018 ALLOCATE( time_factor(emt_att%ncat) ) 1019 ! 1020 !-- Read-in hourly emission time factor 1021 IF ( TRIM( time_fac_type ) == "HOUR" ) THEN 1022 1023 ! 1024 !-- Update time indices 1074 1075 ! 1076 !-- LOD 1 (DEFAULT MODE) 1077 1078 ELSEIF ( emiss_lod == 1 ) THEN 1079 1080 ! for reference (ecc) 1081 ! ELSEIF ( TRIM( mode_emis ) == "DEFAULT" ) THEN 1082 1083 ! 1084 !-- Allocate array where to store temporary emission values 1085 1086 IF ( .NOT. ALLOCATED(emis) ) ALLOCATE( emis(nys:nyn,nxl:nxr) ) 1087 1088 ! 1089 !-- Allocate time factor per category 1090 1091 ALLOCATE( time_factor(emt_att%ncat) ) 1092 1093 ! 1094 !-- Read-in hourly emission time factor 1095 1096 IF ( TRIM(time_fac_type) == "HOUR" ) THEN 1097 1098 ! 1099 !-- Update time indices 1100 1025 1101 CALL time_default_indices( month_of_year, day_of_month, hour_of_day, index_hh ) 1026 ! 1027 !-- Check if the index is less or equal to the temporal dimension of HOURLY emission files 1028 IF ( index_hh <= SIZE( emt_att%hourly_emis_time_factor(1,:) ) ) THEN 1029 ! 1030 !-- Read-in the correspondant time factor 1102 1103 ! 1104 !-- Check if the index is less or equal to the temporal dimension of HOURLY emission files 1105 1106 IF ( index_hh <= SIZE( emt_att%hourly_emis_time_factor(1,:) ) ) THEN 1107 1108 ! 1109 !-- Read-in the correspondant time factor 1110 1031 1111 time_factor(:) = emt_att%hourly_emis_time_factor(:,index_hh) 1112 1113 ! 1114 !-- Error check (time out of range) 1032 1115 1033 1116 ELSE … … 1038 1121 1039 1122 ENDIF 1040 ! 1041 !-- Read-in MDH emissions time factors 1042 ELSEIF ( TRIM( time_fac_type ) == "MDH" ) THEN 1043 1044 ! 1045 !-- Update time indices 1123 1124 ! 1125 !-- Read-in MDH emissions time factors 1126 1127 ELSEIF ( TRIM( time_fac_type ) == "MDH" ) THEN 1128 1129 ! 1130 !-- Update time indices 1046 1131 CALL time_default_indices( daytype_mdh, month_of_year, day_of_month, & 1047 1132 hour_of_day, index_mm, index_dd,index_hh ) 1048 1133 1049 ! 1050 !-- Check if the index is less or equal to the temporal dimension of MDH emission files 1051 IF ( ( index_hh + index_dd + index_mm) <= SIZE( emt_att%mdh_emis_time_factor(1,:) ) ) THEN 1052 ! 1053 !-- Read-in the correspondant time factor 1054 time_factor(:) = emt_att%mdh_emis_time_factor(:,index_mm) * emt_att%mdh_emis_time_factor(:,index_dd) * & 1055 emt_att%mdh_emis_time_factor(:,index_hh) 1134 ! 1135 !-- Check if the index is less or equal to the temporal dimension of MDH emission files 1136 1137 IF ( ( index_hh + index_dd + index_mm) <= SIZE( emt_att%mdh_emis_time_factor(1,:) ) ) THEN 1138 1139 ! 1140 !-- Read in corresponding time factor 1141 1142 time_factor(:) = emt_att%mdh_emis_time_factor(:,index_mm) * & 1143 emt_att%mdh_emis_time_factor(:,index_dd) * & 1144 emt_att%mdh_emis_time_factor(:,index_hh) 1145 1146 ! 1147 !-- Error check (MDH time factor not provided) 1056 1148 1057 1149 ELSE … … 1061 1153 CALL message( 'chem_emissions_setup', 'CM0449', 2, 2, 0, 6, 0 ) 1062 1154 1063 ENDIF 1155 ENDIF 1156 1157 ! 1158 !-- Error check (no time factor defined) 1064 1159 1065 1160 ELSE … … 1071 1166 ENDIF 1072 1167 1073 ! 1074 !-- PARAMETERIZED MODE 1075 ELSEIF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1168 ! 1169 !-- PARAMETERIZED MODE 1170 1171 ELSEIF ( emiss_lod == 0 ) THEN 1172 1173 1174 ! for reference (ecc) 1175 ! ELSEIF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1076 1176 1077 ! 1078 !-- assign constant values of time factors, diurnal time profile for traffic sector 1079 par_emis_time_factor( : ) = & 1080 (/ 0.009, 0.004, 0.004, 0.009, 0.029, 0.039, 0.056, 0.053, 0.051, 0.051, 0.052, 0.055, & 1081 0.059, 0.061, 0.064, 0.067, 0.069, 0.069, 0.049, 0.039, 0.039, 0.029, 0.024, 0.019 /) 1177 ! 1178 !-- assign constant values of time factors, diurnal profile for traffic sector 1179 1180 par_emis_time_factor( : ) = (/ 0.009, 0.004, 0.004, 0.009, 0.029, 0.039, & 1181 0.056, 0.053, 0.051, 0.051, 0.052, 0.055, & 1182 0.059, 0.061, 0.064, 0.067, 0.069, 0.069, & 1183 0.049, 0.039, 0.039, 0.029, 0.024, 0.019 /) 1082 1184 1083 IF ( .NOT. ALLOCATED( time_factor ) ) ALLOCATE( time_factor(1) ) 1084 1085 ! 1086 !-- Get time-factor for specific hour 1185 IF ( .NOT. ALLOCATED (time_factor) ) ALLOCATE (time_factor(1)) 1186 1187 ! 1188 !-- Get time-factor for specific hour 1189 1087 1190 index_hh = hour_of_day 1088 1089 1191 time_factor(1) = par_emis_time_factor(index_hh) 1090 1192 1091 ENDIF 1193 ENDIF ! emiss_lod 1092 1194 1093 1195 1094 ! 1095 !-- Emission distribution calculation 1096 1097 ! 1098 !-- PARAMETERIZED case 1099 IF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1100 1101 DO ispec = 1, nspec_out 1102 1103 ! 1104 !-- Units are micromoles/m**2*day (or kilograms/m**2*day for PMs) 1105 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = surface_csflux(match_spec_input(ispec)) * & 1106 time_factor(1) * hour_to_s 1196 ! 1197 !-- Emission distribution calculation 1198 1199 ! 1200 !-- LOD 0 (PARAMETERIZED mode) 1201 1202 IF ( emiss_lod == 0 ) THEN 1203 1204 ! for reference (ecc) 1205 ! IF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1206 1207 DO ispec = 1, n_matched_vars 1208 1209 ! 1210 !-- Units are micromoles/m**2*day (or kilograms/m**2*day for PMs) 1211 1212 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1213 surface_csflux(match_spec_input(ispec)) * & 1214 time_factor(1) * hour_to_s 1107 1215 1108 1216 ENDDO 1109 1217 1110 !1111 !-- PRE-PROCESSED case1112 ELSEIF ( TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN1113 1114 !1115 !-- Cycle over species:1116 !-- nspec_out represents the number of species in common between the emission input data1117 !-- and the chemistry mechanism used1118 DO ispec=1,nspec_out1119 1120 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emt(match_spec_input(ispec))% &1121 preproc_emission_data(index_hh,1,nys+1:nyn+1,nxl+1:nxr+1) * &1122 con_factor1123 1218 1124 ENDDO 1125 1126 ! 1127 !-- DEFAULT case 1128 ELSEIF ( TRIM( mode_emis ) == "DEFAULT" ) THEN 1129 1130 ! 1131 !-- Allocate array for the emission value corresponding to a specific category and time factor 1132 ALLOCATE( delta_emis(nys:nyn,nxl:nxr) ) 1133 1134 ! 1135 !-- Cycle over categories 1219 ! 1220 !-- LOD 1 (DEFAULT mode) 1221 1222 1223 ELSEIF ( emiss_lod == 1 ) THEN 1224 1225 ! for referene (ecc) 1226 ! ELSEIF ( TRIM( mode_emis ) == "DEFAULT" ) THEN 1227 1228 ! 1229 !-- Allocate array for the emission value corresponding to a specific category and time factor 1230 1231 ALLOCATE (delta_emis(nys:nyn,nxl:nxr)) 1232 1233 ! 1234 !-- Cycle over categories 1235 1136 1236 DO icat = 1, emt_att%ncat 1137 1237 1138 ! 1139 !-- Cycle over Species 1140 !-- nspec_out represents the number of species in common between the emission input data 1141 !-- and the chemistry mechanism used 1142 DO ispec = 1, nspec_out 1143 1144 emis(nys:nyn,nxl:nxr) = emt(match_spec_input(ispec))%default_emission_data(icat,nys+1:nyn+1,nxl+1:nxr+1) 1145 1146 1147 ! 1148 !-- NOx 1149 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "NO" ) THEN 1238 ! 1239 !-- Cycle over Species: n_matched_vars represents the number of species 1240 !-- in common between the emission input data and the chemistry mechanism used 1241 1242 DO ispec = 1, n_matched_vars 1243 1244 emis(nys:nyn,nxl:nxr) = & 1245 emt(match_spec_input(ispec))% & 1246 default_emission_data(icat,nys+1:nyn+1,nxl+1:nxr+1) 1247 1248 ! 1249 !-- NO 1250 1251 IF ( TRIM(spc_names(match_spec_model(ispec))) == "NO" ) THEN 1150 1252 1151 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1152 emt_att%nox_comp(icat,1) * con_factor * hour_per_day 1153 1154 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1155 delta_emis(nys:nyn,nxl:nxr) 1156 1157 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "NO2" ) THEN 1158 1159 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1160 emt_att%nox_comp(icat,2) * con_factor * hour_per_day 1161 1162 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1163 delta_emis(nys:nyn,nxl:nxr) 1164 1165 ! 1166 !-- SOx 1167 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "SO2" ) THEN 1253 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1254 time_factor(icat) * & 1255 emt_att%nox_comp(icat,1) * & 1256 con_factor * hour_per_day 1257 1258 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1259 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1260 delta_emis(nys:nyn,nxl:nxr) 1261 ! 1262 !-- NO2 1263 1264 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "NO2" ) THEN 1265 1266 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1267 time_factor(icat) * & 1268 emt_att%nox_comp(icat,2) * & 1269 con_factor * hour_per_day 1270 1271 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1272 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1273 delta_emis(nys:nyn,nxl:nxr) 1274 1275 ! 1276 !-- SO2 1277 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "SO2" ) THEN 1168 1278 1169 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1170 emt_att%sox_comp(icat,1) * con_factor * hour_per_day 1171 1172 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1173 delta_emis(nys:nyn,nxl:nxr) 1174 1175 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "SO4" ) THEN 1279 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1280 time_factor(icat) * & 1281 emt_att%sox_comp(icat,1) * & 1282 con_factor * hour_per_day 1283 1284 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1285 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1286 delta_emis(nys:nyn,nxl:nxr) 1287 1288 ! 1289 !-- SO4 1290 1291 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "SO4" ) THEN 1292 1176 1293 1177 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1178 emt_att%sox_comp(icat,2) * con_factor * hour_per_day 1179 1180 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1181 delta_emis(nys:nyn,nxl:nxr) 1182 1183 1184 ! 1185 !-- PMs 1186 !-- PM1 1187 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1" ) THEN 1188 1189 ! 1190 !-- Cycle over PM1 components 1191 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,1) ) 1192 1193 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1194 emt_att%pm_comp(icat,i_pm_comp,1) * con_factor * hour_per_day 1195 1196 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1197 delta_emis(nys:nyn,nxl:nxr) 1294 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1295 time_factor(icat) * & 1296 emt_att%sox_comp(icat,2) * & 1297 con_factor * hour_per_day 1298 1299 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1300 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1301 delta_emis(nys:nyn,nxl:nxr) 1302 1303 1304 ! 1305 !-- PM1 1306 1307 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" ) THEN 1308 1309 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,1) ) ! cycle through components 1310 1311 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1312 time_factor(icat) * & 1313 emt_att%pm_comp(icat,i_pm_comp,1) * & 1314 con_factor * hour_per_day 1315 1316 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1317 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1318 delta_emis(nys:nyn,nxl:nxr) 1319 1198 1320 ENDDO 1199 1321 1200 ! 1201 !-- PM2.5 1202 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM25" ) THEN 1203 1204 ! 1205 !-- Cycle over PM2.5 components 1206 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,2) ) 1207 1208 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1209 emt_att%pm_comp(icat,i_pm_comp,2) * con_factor * hour_per_day 1210 1211 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1212 delta_emis(nys:nyn,nxl:nxr) 1322 ! 1323 !-- PM2.5 1324 1325 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "PM25" ) THEN 1326 1327 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,2) ) ! cycle through components 1328 1329 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1330 time_factor(icat) * & 1331 emt_att%pm_comp(icat,i_pm_comp,2) * & 1332 con_factor * hour_per_day 1333 1334 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1335 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1336 delta_emis(nys:nyn,nxl:nxr) 1213 1337 1214 1338 ENDDO 1215 1339 1216 ! 1217 !-- PM10 1218 ELSEIF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM10" ) THEN 1219 1220 ! 1221 !-- Cycle over PM10 components 1222 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,3) ) 1223 1224 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & !< kg/m2*s 1225 emt_att%pm_comp(icat,i_pm_comp,3) * con_factor * hour_per_day 1226 1227 emis_distribution(1,nys:nyn,nxl:nxr,ispec)=emis_distribution(1,nys:nyn,nxl:nxr,ispec)+ & 1228 delta_emis(nys:nyn,nxl:nxr) 1340 ! 1341 !-- PM10 1342 1343 ELSEIF ( TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1344 1345 DO i_pm_comp = 1, SIZE( emt_att%pm_comp(1,:,3) ) ! cycle through components 1346 1347 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & ! kg/m2/s 1348 time_factor(icat) * & 1349 emt_att%pm_comp(icat,i_pm_comp,3) * & 1350 con_factor * hour_per_day 1351 1352 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1353 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1354 delta_emis(nys:nyn,nxl:nxr) 1229 1355 1230 1356 ENDDO 1231 1357 1232 ! 1233 !-- VOCs 1234 ELSEIF ( SIZE( match_spec_voc_input ) > 0 ) THEN 1235 1236 DO ivoc = 1, SIZE( match_spec_voc_input ) 1237 1238 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == TRIM( emt_att%voc_name(ivoc) ) ) THEN 1239 1240 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & 1241 emt_att%voc_comp(icat,match_spec_voc_input(ivoc)) * & 1242 con_factor * hour_per_day 1243 1244 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1245 delta_emis(nys:nyn,nxl:nxr) 1358 ! 1359 !-- VOCs 1360 1361 ELSEIF ( SIZE( match_spec_voc_input ) > 0 ) THEN 1362 1363 DO ivoc = 1, SIZE( match_spec_voc_input ) ! cycle through components 1364 1365 IF ( TRIM(spc_names(match_spec_model(ispec))) == & 1366 TRIM(emt_att%voc_name(ivoc)) ) THEN 1367 1368 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & 1369 time_factor(icat) * & 1370 emt_att%voc_comp(icat,match_spec_voc_input(ivoc)) * & 1371 con_factor * hour_per_day 1372 1373 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1374 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1375 delta_emis(nys:nyn,nxl:nxr) 1246 1376 1247 1377 ENDIF … … 1249 1379 ENDDO 1250 1380 1251 ! 1252 !-- any other species 1381 ! 1382 !-- any other species 1383 1253 1384 ELSE 1254 1385 1255 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * time_factor(icat) * & 1256 con_factor * hour_per_day 1257 1258 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1259 delta_emis(nys:nyn,nxl:nxr) 1260 1261 ENDIF 1386 delta_emis(nys:nyn,nxl:nxr) = emis(nys:nyn,nxl:nxr) * & 1387 time_factor(icat) * & 1388 con_factor * hour_per_day 1389 1390 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1391 emis_distribution(1,nys:nyn,nxl:nxr,ispec) + & 1392 delta_emis(nys:nyn,nxl:nxr) 1393 1394 ENDIF ! TRIM spc_names 1262 1395 1263 1396 emis(:,:)= 0 … … 1269 1402 ENDDO 1270 1403 1271 ENDIF 1404 ! 1405 !-- LOD 2 (PRE-PROCESSED mode) 1406 1407 ELSEIF ( emiss_lod == 2 ) THEN 1408 1409 ! for reference (ecc) 1410 ! ELSEIF ( TRIM( mode_emis ) == "PRE-PROCESSED" ) THEN 1411 1412 ! 1413 !-- Cycle over species: n_matched_vars represents the number of species 1414 !-- in common between the emission input data and the chemistry mechanism used 1415 1416 DO ispec = 1, n_matched_vars 1417 1418 ! (ecc) 1419 emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1420 emt(match_spec_input(ispec))% & 1421 preproc_emission_data(index_hh,1,nys+1:nyn+1,nxl+1:nxr+1) * & 1422 con_factor 1423 1424 1425 ! emis_distribution(1,nys:nyn,nxl:nxr,ispec) = & 1426 ! emt(match_spec_input(ispec))% & 1427 ! preproc_emission_data(index_hh,1,:,:) * & 1428 ! con_factor 1429 ENDDO 1430 1431 ENDIF ! emiss_lod 1272 1432 1273 1433 1274 1434 ! 1275 1435 !-- Cycle to transform x,y coordinates to the one of surface_mod and to assign emission values to cssws 1276 ! 1277 !-- PARAMETERIZED mode 1278 ! 1279 !-- Units of inputs are micromoles/(m**2*s) 1280 IF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1281 1282 IF ( street_type_f%from_file ) THEN 1283 1284 ! 1285 !-- Streets are lsm surfaces, hence, no usm surface treatment required. 1286 !-- However, urban surface may be initialized via default initialization 1287 !-- in surface_mod, e.g. at horizontal urban walls that are at k == 0 1288 !-- (building is lower than the first grid point). Hence, in order to 1289 !-- have only emissions at streets, set the surfaces emissions to zero 1290 !-- at urban walls. 1291 IF ( surf_usm_h%ns >=1 ) surf_usm_h%cssws = 0.0_wp 1292 ! 1293 !-- Now, treat land-surfaces. 1436 1437 ! 1438 !-- LOD 0 (PARAMETERIZED mode) 1439 !-- Units of inputs are micromoles/m2/s 1440 1441 IF ( emiss_lod == 0 ) THEN 1442 ! for reference (ecc) 1443 ! IF ( TRIM( mode_emis ) == "PARAMETERIZED" ) THEN 1444 1445 IF (street_type_f%from_file) THEN 1446 1447 ! 1448 !-- Streets are lsm surfaces, hence, no usm surface treatment required. 1449 !-- However, urban surface may be initialized via default initialization 1450 !-- in surface_mod, e.g. at horizontal urban walls that are at k == 0 1451 !-- (building is lower than the first grid point). Hence, in order to 1452 !-- have only emissions at streets, set the surfaces emissions to zero 1453 !-- at urban walls. 1454 1455 IF ( surf_usm_h%ns >=1 ) surf_usm_h%cssws = 0.0_wp 1456 1457 ! 1458 !-- Treat land-surfaces. 1459 1294 1460 DO m = 1, surf_lsm_h%ns 1461 1295 1462 i = surf_lsm_h%i(m) 1296 1463 j = surf_lsm_h%j(m) 1297 1464 k = surf_lsm_h%k(m) 1298 1465 1299 IF ( street_type_f%var(j,i) >= main_street_id .AND. street_type_f%var(j,i) < max_street_id ) THEN 1300 1301 ! 1302 !-- Cycle over matched species 1303 DO ispec = 1, nspec_out 1304 1305 ! 1306 !-- PMs are already in kilograms 1307 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1 " & 1308 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM25" & 1309 .OR. TRIM( spc_names(match_spec_model(ispec)) )=="PM10") THEN 1310 1311 ! 1312 !-- kg/(m^2*s) * kg/m^3 1313 surf_lsm_h%cssws(match_spec_model(ispec),m) = emiss_factor_main(match_spec_input(ispec)) * & 1314 emis_distribution(1,j,i,ispec) * & !< in kg/(m^2*s) 1315 rho_air(k) !< in kg/m^3 1466 IF ( street_type_f%var(j,i) >= main_street_id .AND. & 1467 street_type_f%var(j,i) < max_street_id ) THEN 1468 1469 ! 1470 !-- Cycle over matched species 1471 1472 DO ispec = 1, n_matched_vars 1473 1474 ! 1475 !-- PMs are already in kilograms 1476 1477 IF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" .OR. & 1478 TRIM(spc_names(match_spec_model(ispec))) == "PM25" .OR. & 1479 TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1480 1481 ! 1482 !-- kg/(m^2*s) * kg/m^3 1483 surf_lsm_h%cssws(match_spec_model(ispec),m) = & 1484 emiss_factor_main(match_spec_input(ispec)) * & 1485 emis_distribution(1,j,i,ispec) * & ! kg/(m^2*s) 1486 rho_air(k) ! kg/m^3 1316 1487 1317 ! 1318 !-- Other Species 1319 !-- Inputs are micromoles 1488 ! 1489 !-- Other Species 1490 !-- Inputs are micromoles 1491 1320 1492 ELSE 1321 1493 1322 ! 1323 !-- ppm/s *m *kg/m^3 1324 surf_lsm_h%cssws(match_spec_model(ispec),m) = emiss_factor_main(match_spec_input(ispec)) * & 1325 emis_distribution(1,j,i,ispec) * & !< in micromoles/(m^2*s) 1326 conv_to_ratio(k,j,i) * & !< in m^3/Nmole 1327 rho_air(k) !< in kg/m^3 1494 ! 1495 !-- ppm/s *m *kg/m^3 1496 surf_lsm_h%cssws(match_spec_model(ispec),m) = & 1497 emiss_factor_main(match_spec_input(ispec)) * & 1498 emis_distribution(1,j,i,ispec) * & ! micromoles/(m^2*s) 1499 conv_to_ratio(k,j,i) * & ! m^3/Nmole 1500 rho_air(k) ! kg/m^3 1328 1501 1329 1502 ENDIF 1330 1503 1331 ENDDO 1332 1333 1334 ELSEIF ( street_type_f%var(j,i) >= side_street_id .AND. street_type_f%var(j,i) < main_street_id ) THEN 1335 1336 ! 1337 !-- Cycle over matched species 1338 DO ispec = 1, nspec_out 1339 1340 ! 1341 !-- PMs are already in kilograms 1342 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1" & 1343 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM25" & 1344 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM10" ) THEN 1345 1346 ! 1347 !-- kg/(m^2*s) * kg/m^3 1348 surf_lsm_h%cssws(match_spec_model(ispec),m) = emiss_factor_side(match_spec_input(ispec)) * & 1349 emis_distribution(1,j,i,ispec) * & !< in kg/(m^2*s) 1350 rho_air(k) !< in kg/m^3 1351 ! 1352 !-- Other species 1353 !-- Inputs are micromoles 1504 ENDDO ! ispec 1505 1506 1507 ELSEIF ( street_type_f%var(j,i) >= side_street_id .AND. & 1508 street_type_f%var(j,i) < main_street_id ) THEN 1509 1510 ! 1511 !-- Cycle over matched species 1512 1513 DO ispec = 1, n_matched_vars 1514 1515 ! 1516 !-- PMs are already in kilograms 1517 1518 IF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" .OR. & 1519 TRIM(spc_names(match_spec_model(ispec))) == "PM25" .OR. & 1520 TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1521 1522 ! 1523 !-- kg/(m^2*s) * kg/m^3 1524 surf_lsm_h%cssws(match_spec_model(ispec),m) = & 1525 emiss_factor_side(match_spec_input(ispec)) * & 1526 emis_distribution(1,j,i,ispec) * & ! kg/(m^2*s) 1527 rho_air(k) ! kg/m^3 1528 ! 1529 !-- Other species 1530 !-- Inputs are micromoles 1531 1354 1532 ELSE 1355 1356 ! 1357 !-- ppm/s *m *kg/m^3 1358 surf_lsm_h%cssws(match_spec_model(ispec),m) = emiss_factor_side(match_spec_input(ispec)) * & 1359 emis_distribution(1,j,i,ispec) * & !< in micromoles/(m^2*s) 1360 conv_to_ratio(k,j,i) * & !< in m^3/Nmole 1361 rho_air(k) !< in kg/m^3 1533 1534 ! 1535 !-- ppm/s *m *kg/m^3 1536 1537 surf_lsm_h%cssws(match_spec_model(ispec),m) = & 1538 emiss_factor_side(match_spec_input(ispec)) * & 1539 emis_distribution(1,j,i,ispec) * & ! micromoles/(m^2*s) 1540 conv_to_ratio(k,j,i) * & ! m^3/Nmole 1541 rho_air(k) ! kg/m^3 1542 1362 1543 ENDIF 1363 1544 1364 ENDDO 1545 ENDDO ! ispec 1546 1547 ! 1548 !-- If no street type is defined, then assign zero emission to all the species 1365 1549 1366 1550 ELSE 1367 1551 1368 !1369 !-- If no street type is defined, then assign zero emission to all the species1370 1552 surf_lsm_h%cssws(:,m) = 0.0_wp 1371 1553 1372 ENDIF 1373 1374 ENDDO 1375 1376 ENDIF 1377 1378 ! 1379 !-- For both DEFAULT and PRE-PROCESSED mode 1554 ENDIF ! street type 1555 1556 ENDDO ! m 1557 1558 ENDIF ! street_type_f%from_file 1559 1560 1561 ! 1562 !-- LOD 1 (DEFAULT) and LOD 2 (PRE-PROCESSED) 1563 1564 1380 1565 ELSE 1381 1566 1382 1567 1383 DO ispec = 1, n spec_out1568 DO ispec = 1, n_matched_vars 1384 1569 1385 1570 ! 1386 1571 !-- Default surfaces 1572 1387 1573 DO m = 1, surf_def_h(0)%ns 1388 1574 … … 1390 1576 j = surf_def_h(0)%j(m) 1391 1577 1392 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN1393 1394 1395 1396 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1"&1397 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM25"&1398 .OR. TRIM( spc_names(match_spec_model(ispec))) == "PM10" ) THEN1578 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN 1579 1580 ! 1581 !-- PMs 1582 IF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" .OR. & 1583 TRIM(spc_names(match_spec_model(ispec))) == "PM25" .OR. & 1584 TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1399 1585 1400 ! 1401 !-- kg/(m^2*s) *kg/m^3 kg/(m^2*s) 1402 surf_def_h(0)%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec)* & 1403 rho_air(nzb) !< in kg/m^3 1404 1586 surf_def_h(0)%cssws(match_spec_model(ispec),m) = & ! kg/m2/s * kg/m3 1587 emis_distribution(1,j,i,ispec)* & ! kg/m2/s 1588 rho_air(nzb) ! kg/m^3 1405 1589 1406 1590 ELSE 1407 1591 1408 ! 1409 !-- VOCs 1410 IF ( len_index_voc > 0 .AND. emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1411 ! 1412 !-- (ppm/s) * m * kg/m^3 mole/(m^2/s) 1413 surf_def_h(0)%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1414 conv_to_ratio(nzb,j,i) * & !< in m^3/mole 1415 ratio2ppm * & !< in ppm 1416 rho_air(nzb) !< in kg/m^3 1417 1418 1419 ! 1420 !-- Other species 1592 ! 1593 !-- VOCs 1594 IF ( len_index_voc > 0 .AND. & 1595 emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1596 1597 surf_def_h(0)%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1598 emis_distribution(1,j,i,ispec) * & ! mole/m2/s 1599 conv_to_ratio(nzb,j,i) * & ! m^3/mole 1600 ratio2ppm * & ! ppm 1601 rho_air(nzb) ! kg/m^3 1602 1603 1604 ! 1605 !-- Other species 1606 1421 1607 ELSE 1422 1608 1423 ! 1424 !-- (ppm/s) * m * kg/m^3 kg/(m^2/s) 1425 surf_def_h(0)%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1426 ( 1.0_wp / emt_att%xm(ispec) ) * & !< in mole/kg 1427 conv_to_ratio(nzb,j,i) * & !< in m^3/mole 1428 ratio2ppm * & !< in ppm 1429 rho_air(nzb) !< in kg/m^3 1609 surf_def_h(0)%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1610 emis_distribution(1,j,i,ispec) * & ! kg/m2/s 1611 ( 1.0_wp / emt_att%xm(ispec) ) * & ! mole/kg 1612 conv_to_ratio(nzb,j,i) * & ! m^3/mole 1613 ratio2ppm * & ! ppm 1614 rho_air(nzb) ! kg/m^3 1430 1615 1431 1432 ENDIF 1433 1434 ENDIF 1435 1436 ENDIF 1437 1438 ENDDO 1616 ENDIF ! VOC 1617 1618 ENDIF ! PM 1619 1620 ENDIF ! emis_distribution > 0 1621 1622 ENDDO ! m 1439 1623 1440 1624 ! 1441 !-- LSM surfaces 1442 DO m = 1, surf_lsm_h%ns 1625 !-- LSM surfaces 1626 1627 DO m = 1, surf_lsm_h%ns 1443 1628 1444 1629 i = surf_lsm_h%i(m) … … 1446 1631 k = surf_lsm_h%k(m) 1447 1632 1448 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN 1449 1450 ! 1451 !-- PMs 1452 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1" & 1453 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM25" & 1454 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM10" ) THEN 1455 1456 ! 1457 !-- kg/(m^2*s) * kg/m^3 kg/(m^2*s) 1458 surf_lsm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1459 rho_air(k) !< in kg/m^3 1633 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN 1634 1635 ! 1636 !-- PMs 1637 IF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" .OR. & 1638 TRIM(spc_names(match_spec_model(ispec))) == "PM25" .OR. & 1639 TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1640 1641 surf_lsm_h%cssws(match_spec_model(ispec),m) = & ! kg/m2/s * kg/m3 1642 emis_distribution(1,j,i,ispec) * & ! kg/m2/s 1643 rho_air(k) ! kg/m^3 1460 1644 1461 1645 ELSE 1462 1646 1463 ! 1464 !-- VOCs 1465 IF ( len_index_voc > 0 .AND. emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1466 ! 1467 !-- (ppm/s) * m * kg/m^3 mole/(m^2/s) 1468 surf_lsm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1469 conv_to_ratio(k,j,i) * & !< in m^3/mole 1470 ratio2ppm * & !< in ppm 1471 rho_air(k) !< in kg/m^3 1472 1473 ! 1474 !-- Other species 1647 ! 1648 !-- VOCs 1649 1650 IF ( len_index_voc > 0 .AND. & 1651 emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1652 1653 surf_lsm_h%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1654 emis_distribution(1,j,i,ispec) * & ! mole/m2/s 1655 conv_to_ratio(k,j,i) * & ! m^3/mole 1656 ratio2ppm * & ! ppm 1657 rho_air(k) ! kg/m^3 1658 1659 ! 1660 !-- Other species 1661 1475 1662 ELSE 1476 ! 1477 !-- (ppm/s) * m * kg/m^3 kg/(m^2/s)1478 surf_lsm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * &1479 ( 1.0_wp / emt_att%xm(ispec) ) * & !< inmole/kg1480 conv_to_ratio(k,j,i) * & !< inm^3/mole1481 ratio2ppm * & !< inppm1482 rho_air(k) !< inkg/m^31663 1664 surf_lsm_h%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1665 emis_distribution(1,j,i,ispec) * & ! kg/m2/s 1666 ( 1.0_wp / emt_att%xm(ispec) ) * & ! mole/kg 1667 conv_to_ratio(k,j,i) * & ! m^3/mole 1668 ratio2ppm * & ! ppm 1669 rho_air(k) ! kg/m^3 1483 1670 1484 ENDIF 1485 1486 ENDIF 1487 1488 ENDIF 1489 1490 ENDDO 1491 1492 ! 1493 !-- USM surfaces 1494 DO m = 1, surf_usm_h%ns 1671 ENDIF ! VOC 1672 1673 ENDIF ! PM 1674 1675 ENDIF ! emis_distribution 1676 1677 ENDDO ! m 1678 1679 ! 1680 !-- USM surfaces 1681 1682 DO m = 1, surf_usm_h%ns 1495 1683 1496 1684 i = surf_usm_h%i(m) … … 1498 1686 k = surf_usm_h%k(m) 1499 1687 1500 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN1501 1502 1503 1504 IF ( TRIM( spc_names(match_spec_model(ispec)) ) == "PM1"&1505 .OR. TRIM( spc_names(match_spec_model(ispec)) ) == "PM25"&1506 .OR. TRIM( spc_names(match_spec_model(ispec))) == "PM10" ) THEN1688 IF ( emis_distribution(1,j,i,ispec) > 0.0_wp ) THEN 1689 1690 ! 1691 !-- PMs 1692 IF ( TRIM(spc_names(match_spec_model(ispec))) == "PM1" .OR. & 1693 TRIM(spc_names(match_spec_model(ispec))) == "PM25" .OR. & 1694 TRIM(spc_names(match_spec_model(ispec))) == "PM10" ) THEN 1507 1695 1508 ! 1509 !-- kg/(m^2*s) *kg/m^3 kg/(m^2*s) 1510 surf_usm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec)* & 1511 rho_air(k) !< in kg/m^3 1512 1513 1696 surf_usm_h%cssws(match_spec_model(ispec),m) = & ! kg/m2/s * kg/m3 1697 emis_distribution(1,j,i,ispec)* & ! kg/m2/s 1698 rho_air(k) ! kg/m^3 1699 1514 1700 ELSE 1515 1701 1516 ! 1517 !-- VOCs 1518 IF ( len_index_voc > 0 .AND. emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1519 ! 1520 !-- (ppm/s) * m * kg/m^3 mole/(m^2/s) 1521 surf_usm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1522 conv_to_ratio(k,j,i) * & !< in m^3/mole 1523 ratio2ppm * & !< in ppm 1524 rho_air(k) !< in kg/m^3 1525 1526 ! 1527 !-- Other species 1702 ! 1703 !-- VOCs 1704 IF ( len_index_voc > 0 .AND. & 1705 emt_att%species_name(match_spec_input(ispec)) == "VOC" ) THEN 1706 1707 surf_usm_h%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1708 emis_distribution(1,j,i,ispec) * & ! m2/s 1709 conv_to_ratio(k,j,i) * & ! m^3/mole 1710 ratio2ppm * & ! ppm 1711 rho_air(k) ! kg/m^3 1712 1713 ! 1714 !-- Other species 1528 1715 ELSE 1529 1716 1530 ! 1531 !-- (ppm/s) * m * kg/m^3 kg/(m^2/s) 1532 surf_usm_h%cssws(match_spec_model(ispec),m) = emis_distribution(1,j,i,ispec) * & 1533 ( 1.0_wp / emt_att%xm(ispec) ) * & !< in mole/kg 1534 conv_to_ratio(k,j,i) * & !< in m^3/mole 1535 ratio2ppm* & !< in ppm 1536 rho_air(k) !< in kg/m^3 1537 1538 1539 ENDIF 1540 1541 ENDIF 1542 1543 ENDIF 1544 1545 ENDDO 1717 surf_usm_h%cssws(match_spec_model(ispec),m) = & ! ppm/s * m * kg/m3 1718 emis_distribution(1,j,i,ispec) * & ! kg/m2/s 1719 ( 1.0_wp / emt_att%xm(ispec) ) * & ! mole/kg 1720 conv_to_ratio(k,j,i) * & ! m^3/mole 1721 ratio2ppm* & ! ppm 1722 rho_air(k) ! kg/m^3 1723 1724 1725 ENDIF ! VOC 1726 1727 ENDIF ! PM 1728 1729 ENDIF ! emis_distribution 1730 1731 ENDDO ! m 1546 1732 1547 1733 ENDDO … … 1549 1735 ENDIF 1550 1736 1551 ! 1552 !-- Deallocate time_factor in case of DEFAULT mode) 1553 IF ( ALLOCATED ( time_factor ) ) DEALLOCATE( time_factor ) 1737 ! 1738 !-- Deallocate time_factor in case of DEFAULT mode) 1739 1740 IF ( ALLOCATED (time_factor) ) DEALLOCATE (time_factor) 1554 1741 1555 1742 ENDIF -
palm/trunk/SOURCE/chem_modules.f90
r3877 r3968 27 27 ! ----------------- 28 28 ! $Id$ 29 ! - introduced namelist item chem_modules@emiss_lod as future 30 ! - replacement to chem_modules@mode_emis. Currently keeping both 31 ! for backward compatibility. chem_modules@mode_emis will be 32 ! depreciated upon migration of all dependent modules (e.g., salsa) 33 ! to chem_modules@emiss_lod 34 ! 35 ! (ecc) 20190513 replaced nspec_out with n_matched_vars 36 ! 37 ! 3877 2019-04-08 19:09:16Z knoop 29 38 ! Formatting, clean-up, clarified/corrected comments 30 39 ! … … 102 111 INTEGER(iwp) :: cs_pr_count = 0 !< counter for chemical species profiles 103 112 INTEGER(iwp) :: cs_vertical_gradient_level_ind(99,10) = -9999 !< grid index values of cs_vertical_gradient_level 113 INTEGER(iwp) :: emiss_lod = -1 !< namelist parameter: chem emission LOD (same as mode_emis) 114 !< -1 = unassigned, 0 = parameterized, 1 = default, 2 = pre-processed 104 115 INTEGER(iwp) :: ibc_cs_b !< integer flag for bc_cs_b 105 116 INTEGER(iwp) :: ibc_cs_t !< integer flag for bc_cs_t … … 107 118 INTEGER(iwp) :: max_pr_cs = 0 !< 108 119 INTEGER(iwp) :: max_street_id = 0 !< namelist parameter: upper bound of main street IDs (OpenStreetMaps) for PARAMETERIZED mode 109 INTEGER(iwp) :: n spec_out !< output of routine chem_emis_matching with.....???120 INTEGER(iwp) :: n_matched_vars !< number of matched emissions variables 110 121 INTEGER(iwp) :: side_street_id = 0 !< namelist parameter: lower bound of side street IDs (OpenStreetMaps) for PARAMETERIZED mode 111 122 -
palm/trunk/SOURCE/chemistry_model_mod.f90
r3930 r3968 27 27 ! ----------------- 28 28 ! $Id$ 29 ! - added "emiss_lod" which serves the same function as "mode_emis" 30 ! both will be synchronized with emiss_lod having pirority over 31 ! mode_emis (see informational messages) 32 ! - modified existing error message and introduced new informational messages 33 ! - CM0436 - now also applies to invalid LOD settings 34 ! - CM0463 - emiss_lod take precedence in case of conflict with mod_emis 35 ! - CM0464 - emiss_lod valued assigned based on mode_emis if undefined 36 ! 37 ! 3930 2019-04-24 14:57:18Z forkel 29 38 ! Changed chem_non_transport_physics to chem_non_advective_processes 30 39 ! … … 1682 1691 ! 1683 1692 !-- Emission mode info 1684 IF ( mode_emis == "DEFAULT" ) THEN 1685 WRITE( io, 5 ) 1686 ELSEIF ( mode_emis == "PARAMETERIZED" ) THEN 1687 WRITE( io, 6 ) 1688 ELSEIF ( mode_emis == "PRE-PROCESSED" ) THEN 1689 WRITE( io, 7 ) 1690 ENDIF 1693 !-- At the moment the evaluation is done with both emiss_lod and mode_emis 1694 !-- but once salsa has been migrated to emiss_lod the .OR. mode_emis 1695 !-- conditions can be removed (ecc 20190513) 1696 IF ( (emiss_lod == 1) .OR. (mode_emis == 'DEFAULT') ) THEN 1697 WRITE ( io, 5 ) 1698 ELSEIF ( (emiss_lod == 0) .OR. (mode_emis == 'PARAMETERIZED') ) THEN 1699 WRITE ( io, 6 ) 1700 ELSEIF ( (emiss_lod == 2) .OR. (mode_emis == 'PRE-PROCESSED') ) THEN 1701 WRITE ( io, 7 ) 1702 ENDIF 1691 1703 ! 1692 1704 !-- Photolysis scheme info … … 2209 2221 decycle_method, & 2210 2222 deposition_dry, & 2211 emissions_anthropogenic, & 2223 emissions_anthropogenic, & 2224 emiss_lod, & 2212 2225 emiss_factor_main, & 2213 2226 emiss_factor_side, & … … 2271 2284 ! 2272 2285 !-- check for emission mode for chem species 2273 IF ( (mode_emis /= 'PARAMETERIZED') .AND. ( mode_emis /= 'DEFAULT' ) .AND. ( mode_emis /= 'PRE-PROCESSED' ) ) THEN 2274 message_string = 'Incorrect mode_emiss option select. Please check spelling' 2275 CALL message( 'chem_check_parameters', 'CM0436', 1, 2, 0, 6, 0 ) 2286 2287 IF ( emiss_lod < 0 ) THEN !- if LOD not defined in namelist 2288 IF ( ( mode_emis /= 'PARAMETERIZED' ) .AND. & 2289 ( mode_emis /= 'DEFAULT' ) .AND. & 2290 ( mode_emis /= 'PRE-PROCESSED' ) ) THEN 2291 message_string = 'Incorrect mode_emiss option select. Please check spelling' 2292 CALL message( 'chem_check_parameters', 'CM0436', 1, 2, 0, 6, 0 ) 2293 ENDIF 2294 ELSE 2295 IF ( ( emiss_lod /= 0 ) .AND. & 2296 ( emiss_lod /= 1 ) .AND. & 2297 ( emiss_lod /= 2 ) ) THEN 2298 message_string = 'Invalid value for emiss_lod (0, 1, or 2)' 2299 CALL message( 'chem_check_parameters', 'CM0436', 1, 2, 0, 6, 0 ) 2300 ENDIF 2301 ENDIF 2302 2303 ! for reference (ecc) 2304 ! IF ( (mode_emis /= 'PARAMETERIZED') .AND. ( mode_emis /= 'DEFAULT' ) .AND. ( mode_emis /= 'PRE-PROCESSED' ) ) THEN 2305 ! message_string = 'Incorrect mode_emiss option select. Please check spelling' 2306 ! CALL message( 'chem_check_parameters', 'CM0436', 1, 2, 0, 6, 0 ) 2307 ! ENDIF 2308 2309 ! 2310 !-- conflict resolution for emiss_lod and mode_emis 2311 !-- 1) if emiss_lod is defined, have mode_emis assume same setting as emiss_lod 2312 !-- 2) if emiss_lod it not defined, have emiss_lod assuem same setting as mode_emis 2313 !-- this check is in place to retain backward compatibility with salsa until the 2314 !-- code is migrated completed to emiss_lod 2315 IF ( emiss_lod >= 0 ) THEN 2316 SELECT CASE ( emiss_lod ) 2317 CASE (0) !- parameterized mode 2318 mode_emis = 'PARAMETERIZED' 2319 CASE (1) !- default mode 2320 mode_emis = 'DEFAULT' 2321 CASE (2) !- preprocessed mode 2322 mode_emis = 'PRE-PROCESSED' 2323 END SELECT 2324 2325 message_string = 'Synchronizing mode_emis to defined emiss_lod' // & 2326 CHAR(10) // ' ' // & 2327 'NOTE - mode_emis will be depreciated in future releases' // & 2328 CHAR(10) // ' ' // & 2329 'please use emiss_lod to define emission mode' 2330 2331 CALL message ( 'parin_chem', 'CM0463', 0, 0, 0, 6, 0 ) 2332 ELSE ! if emiss_lod is not set 2333 SELECT CASE ( mode_emis ) 2334 CASE ('PARAMETERIZED') 2335 emiss_lod = 0 2336 CASE ('DEFAULT') 2337 emiss_lod = 1 2338 CASE ('PRE-PROCESSED') 2339 emiss_lod = 2 2340 END SELECT 2341 2342 message_string = 'emiss_lod undefined. Using existing mod_emiss setting' // & 2343 CHAR(10) // ' ' // & 2344 'NOTE - mode_emis will be depreciated in future releases' // & 2345 CHAR(10) // ' ' // & 2346 ' please use emiss_lod to define emission mode' 2347 2348 CALL message ( 'parin_chem', 'CM0464', 0, 0, 0, 6, 0 ) 2276 2349 ENDIF 2277 2350 -
palm/trunk/SOURCE/netcdf_data_input_mod.f90
r3961 r3968 25 25 ! ----------------- 26 26 ! $Id$ 27 ! - clean-up index notations for emission_values to eliminate magic numbers 28 ! - introduce temporary variable dum_var_5d as well as subroutines 29 ! get_var_5d_real and get_var_5d_real_dynamic 30 ! - remove emission-specific code in generic get_variable routines 31 ! - in subroutine netcdf_data_input_chemistry_data change netCDF LOD 1 32 ! (default) emission_values to the following index order: 33 ! z, y, x, species, category 34 ! - in subroutine netcdf_data_input_chemistry_data 35 ! changed netCDF LOD 2 pre-processed emission_values to the following index 36 ! order: time, z, y, x, species 37 ! - in type chem_emis_att_type replace nspec with n_emiss_species 38 ! but retained nspec for backward compatibility with salsa_mod. (E.C. Chan) 39 ! 40 ! 3961 2019-05-08 16:12:31Z suehring 27 41 ! Revise checks for building IDs and types 28 42 ! … … 289 303 ! Initial revision (suehring) 290 304 ! 291 !292 !293 !294 305 ! Authors: 295 306 ! -------- 296 307 ! @author Matthias Suehring 308 ! @author Edward C. Chan 309 ! @author Emanuele Russo 297 310 ! 298 311 ! Description: … … 300 313 !> Modulue contains routines to input data according to Palm input data 301 314 !> standart using dynamic and static input files. 302 !> @todo - Chemistry: revise reading of netcdf file and ajdust formatting according to standard!!! 315 !> @todo - Chemistry: revise reading of netcdf file and ajdust formatting 316 !> according to standard!!! (ecc/done) 303 317 !> @todo - Order input alphabetically 304 318 !> @todo - Revise error messages and error numbers 305 319 !> @todo - Input of missing quantities (chemical species, emission rates) 306 320 !> @todo - Defninition and input of still missing variable attributes 321 !> (ecc/what are they?) 307 322 !> @todo - Input of initial geostrophic wind profiles with cyclic conditions. 323 !> @todo - remove z dimension from default_emission_data nad preproc_emission_data 324 ! and correpsonding subroutines get_var_5d_real and get_var_5d_dynamic (ecc) 325 !> @todo - decpreciate chem_emis_att_type@nspec (ecc) 326 !> @todo - depreciate subroutines get_variable_4d_to_3d_real and 327 !> get_variable_5d_to_4d_real (ecc) 308 328 !------------------------------------------------------------------------------! 309 329 MODULE netcdf_data_input_mod … … 348 368 CHARACTER(LEN=17) :: char_s = 'ls_forcing_south_' !< leading substring for variables at south boundary 349 369 CHARACTER(LEN=15) :: char_t = 'ls_forcing_top_' !< leading substring for variables at top boundary 350 370 351 371 CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE :: var_names !< list of variable in dynamic input file 352 372 CHARACTER(LEN=100), DIMENSION(:), ALLOCATABLE :: var_names_chem_l !< names of mesoscale nested chemistry variables at left boundary … … 363 383 364 384 LOGICAL :: init = .FALSE. !< flag indicating that offline nesting is already initialized 365 385 366 386 LOGICAL, DIMENSION(:), ALLOCATABLE :: chem_from_file_l !< flags inidicating whether left boundary data for chemistry is in dynamic input file 367 387 LOGICAL, DIMENSION(:), ALLOCATABLE :: chem_from_file_n !< flags inidicating whether north boundary data for chemistry is in dynamic input file … … 491 511 492 512 !-DIMENSIONS 493 INTEGER(iwp) :: nspec=0 !< number of chem species for which emission values are provided 494 INTEGER(iwp) :: ncat=0 !< number of emission categories 495 INTEGER(iwp) :: nvoc=0 !< number of VOCs components 496 INTEGER(iwp) :: npm=0 !< number of PMs components 497 INTEGER(iwp) :: nnox=2 !< number of NOx components: NO and NO2 498 INTEGER(iwp) :: nsox=2 !< number of SOx components: SO and SO4 499 INTEGER(iwp) :: nhoursyear !< number of hours of a specific year in the HOURLY mode 500 ! of the default mode 501 INTEGER(iwp) :: nmonthdayhour !< number of month days and hours in the MDH mode 502 ! of the default mode 503 INTEGER(iwp) :: dt_emission !< Number of emissions timesteps for one year 504 ! in the pre-processed emissions case 513 514 INTEGER(iwp) :: nspec=0 !< no of chem species provided in emission_values 515 INTEGER(iwp) :: n_emiss_species=0 !< no of chem species provided in emission_values 516 !< same function as nspec, which will be depreciated (ecc) 517 518 INTEGER(iwp) :: ncat=0 !< number of emission categories 519 INTEGER(iwp) :: nvoc=0 !< number of VOC components 520 INTEGER(iwp) :: npm=0 !< number of PM components 521 INTEGER(iwp) :: nnox=2 !< number of NOx components: NO and NO2 522 INTEGER(iwp) :: nsox=2 !< number of SOX components: SO and SO4 523 INTEGER(iwp) :: nhoursyear !< number of hours of a specific year in the HOURLY mode 524 !< of the default mode 525 INTEGER(iwp) :: nmonthdayhour !< number of month days and hours in the MDH mode 526 !< of the default mode 527 INTEGER(iwp) :: dt_emission !< Number of emissions timesteps for one year 528 !< in the pre-processed emissions case 505 529 !-- 1d emission input variables 506 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: pm_name !< Names of PMscomponents507 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: cat_name !< Emission categoriesnames508 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: species_name 509 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: voc_name 510 CHARACTER (LEN=25) :: units 511 512 INTEGER(iwp) :: i_hour !< indices for assigning theemission values at different timesteps513 INTEGER(iwp),ALLOCATABLE, DIMENSION(:) :: cat_index !< Index ofemission categories514 INTEGER(iwp),ALLOCATABLE, DIMENSION(:) :: species_index !< Index ofemission chem species515 516 REAL(wp),ALLOCATABLE, DIMENSION(:) :: xm 530 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: pm_name !< Names of PM components 531 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: cat_name !< Emission category names 532 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: species_name !< Names of emission chemical species 533 CHARACTER (LEN=25),ALLOCATABLE, DIMENSION(:) :: voc_name !< Names of VOCs components 534 CHARACTER (LEN=25) :: units !< Units 535 536 INTEGER(iwp) :: i_hour !< indices for assigning emission values at different timesteps 537 INTEGER(iwp),ALLOCATABLE, DIMENSION(:) :: cat_index !< Indices for emission categories 538 INTEGER(iwp),ALLOCATABLE, DIMENSION(:) :: species_index !< Indices for emission chem species 539 540 REAL(wp),ALLOCATABLE, DIMENSION(:) :: xm !< Molecular masses of emission chem species 517 541 518 542 !-- 2d emission input variables 519 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: hourly_emis_time_factor 520 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: mdh_emis_time_factor 521 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: nox_comp 522 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: sox_comp 523 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: voc_comp !< Composition of different VOC components (numbernot fixed)543 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: hourly_emis_time_factor !< Time factors for HOURLY emissions (DEFAULT mode) 544 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: mdh_emis_time_factor !< Time factors for MDH emissions (DEFAULT mode) 545 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: nox_comp !< Composition of NO and NO2 546 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: sox_comp !< Composition of SO2 and SO4 547 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: voc_comp !< Composition of VOC components (not fixed) 524 548 525 549 !-- 3d emission input variables 526 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: pm_comp !< Composition of different PMs components (numbernot fixed)550 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: pm_comp !< Composition of PM components (not fixed) 527 551 528 552 END TYPE chem_emis_att_type 529 553 530 554 531 !-- Data type for the values of chemistry emissions ERUSSO555 !-- Data type for the values of chemistry emissions 532 556 TYPE chem_emis_val_type 533 557 534 !REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: stack_height !< stack height 535 536 !-- 3d emission input variables 537 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: default_emission_data !< Input Values emissions DEFAULT mode 538 539 !-- 4d emission input variables 540 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:,:) :: preproc_emission_data !< Input Values emissions PRE-PROCESSED mode 558 !REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: stack_height !< stack height (ecc / to be implemented) 559 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: default_emission_data !< Emission input values for LOD1 (DEFAULT mode) 560 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:,:) :: preproc_emission_data !< Emission input values for LOD2 (PRE-PROCESSED mode) 541 561 542 562 END TYPE chem_emis_val_type … … 890 910 MODULE PROCEDURE get_variable_4d_real 891 911 MODULE PROCEDURE get_variable_5d_to_4d_real 892 MODULE PROCEDURE get_variable_string 912 MODULE PROCEDURE get_variable_5d_real ! (ecc) temp subroutine 4 reading 5D NC arrays 913 MODULE PROCEDURE get_variable_5d_real_dynamic ! 2B removed as z is out of emission_values 914 MODULE PROCEDURE get_variable_string 893 915 END INTERFACE get_variable 894 916 … … 1380 1402 ! Description: 1381 1403 ! ------------ 1382 !> Reads Chemistry NETCDF Input data, such as emission values, emission species, etc. . 1383 !------------------------------------------------------------------------------! 1404 !> Reads Chemistry NETCDF Input data, such as emission values, emission species, etc. 1405 !------------------------------------------------------------------------------! 1406 1384 1407 SUBROUTINE netcdf_data_input_chemistry_data(emt_att,emt) 1385 1408 1386 1409 USE chem_modules, & 1387 ONLY: mode_emis, time_fac_type, surface_csflux_name1410 ONLY: emiss_lod, time_fac_type, surface_csflux_name 1388 1411 1389 1412 USE control_parameters, & … … 1395 1418 IMPLICIT NONE 1396 1419 1397 TYPE(chem_emis_att_type), INTENT(INOUT) ::emt_att1398 TYPE(chem_emis_val_type), ALLOCATABLE, DIMENSION(:), INTENT(INOUT) ::emt1420 TYPE(chem_emis_att_type), INTENT(INOUT) :: emt_att 1421 TYPE(chem_emis_val_type), ALLOCATABLE, DIMENSION(:), INTENT(INOUT) :: emt 1399 1422 1400 INTEGER(iwp) :: ispec !< index for number of emission species in input 1401 1402 INTEGER(iwp) :: num_vars !< number of variables in netcdf input file 1403 INTEGER(iwp) :: len_dims !< Length of dimension 1404 1405 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:) :: dum_var_3d !< variable for storing temporary data of 3-dimensional 1406 ! variables read from netcdf for chemistry emissions 1407 1408 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: dum_var_4d !< variable for storing temporary data of 5-dimensional 1409 !< variables read from netcdf for chemistry emissions 1410 !-- 1411 !> Start the processing of the data 1412 1413 !> Parameterized mode of the emissions 1414 IF (TRIM(mode_emis)=="PARAMETERIZED" .OR. TRIM(mode_emis)=="parameterized") THEN 1423 INTEGER(iwp) :: i, j, k !< generic counters 1424 INTEGER(iwp) :: ispec !< index for number of emission species in input 1425 INTEGER(iwp) :: len_dims !< Length of dimension 1426 INTEGER(iwp) :: num_vars !< number of variables in netcdf input file 1427 1428 ! 1429 !-- dum_var_4d are designed to read in emission_values from the chemistry netCDF file. 1430 !-- Currently the vestigial "z" dimension in emission_values makes it a 5D array, 1431 !-- hence the corresponding dum_var_5d array. When the "z" dimension is removed 1432 !-- completely, dum_var_4d will be used instead 1433 !-- (ecc 20190425) 1434 1435 ! REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: dum_var_4d !< temp array 4 4D chem emission data 1436 REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:,:) :: dum_var_5d !< temp array 4 5D chem emission data 1437 1438 ! 1439 !-- Start processing data 1440 1441 CALL location_message( 'starting allocation of chemistry emissions arrays', .FALSE. ) 1442 1443 ! 1444 !-- Emission LOD 0 (Parameterized mode) 1445 1446 IF ( emiss_lod == 0 ) THEN 1447 1448 ! for reference (ecc) 1449 ! IF (TRIM(mode_emis) == "PARAMETERIZED" .OR. TRIM(mode_emis) == "parameterized") THEN 1415 1450 1416 1451 ispec=1 1417 emt_att%nspec=0 1418 1419 !number of species 1452 emt_att%n_emiss_species = 0 1453 1454 ! 1455 !-- number of species 1456 1420 1457 DO WHILE (TRIM( surface_csflux_name( ispec ) ) /= 'novalue' ) 1421 1458 1422 emt_att%n spec=emt_att%nspec+11459 emt_att%n_emiss_species = emt_att%n_emiss_species + 1 1423 1460 ispec=ispec+1 1461 ! 1462 !-- followling line retained for compatibility with salsa_mod 1463 !-- which still uses emt_att%nspec heavily (ecc) 1464 1465 emt_att%nspec = emt_att%nspec + 1 1424 1466 1425 1467 ENDDO 1426 1468 1427 !-- allocate emission values data type arrays 1428 ALLOCATE(emt(emt_att%nspec)) 1429 1430 !-- Read EMISSION SPECIES NAMES 1431 1432 !Assign values 1433 ALLOCATE(emt_att%species_name(emt_att%nspec)) 1469 ! 1470 !-- allocate emission values data type arrays 1471 1472 ALLOCATE ( emt(emt_att%n_emiss_species) ) 1473 1474 ! 1475 !-- Read EMISSION SPECIES NAMES 1476 1477 ! 1478 !-- allocate space for strings 1479 1480 ALLOCATE (emt_att%species_name(emt_att%n_emiss_species) ) 1434 1481 1435 DO ispec =1,emt_att%nspec1482 DO ispec = 1, emt_att%n_emiss_species 1436 1483 emt_att%species_name(ispec) = TRIM(surface_csflux_name(ispec)) 1437 1484 ENDDO 1438 1485 1439 1440 !> DEFAULT AND PRE-PROCESSED MODE 1486 ! 1487 !-- LOD 1 (default mode) and LOD 2 (pre-processed mode) 1488 1441 1489 ELSE 1442 1490 1443 #if defined ( __netcdf ) 1491 #if defined ( __netcdf ) 1492 1444 1493 IF ( .NOT. input_pids_chem ) RETURN 1445 1494 1446 !-- Open file in read-only mode 1447 CALL open_read_file( TRIM( input_file_chem ) // & 1448 TRIM( coupling_char ), id_emis ) 1449 !-- inquire number of variables 1450 CALL inquire_num_variables( id_emis, num_vars ) 1451 1452 !-- Get General Dimension Lengths: only number of species and number of categories. 1453 ! the other dimensions depend on the mode of the emissions or on the presence of specific components 1454 !nspecies 1455 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%nspec, 'nspecies' ) 1456 1495 ! 1496 !-- first we allocate memory space for the emission species and then 1497 !-- we differentiate between LOD 1 (default mode) and LOD 2 (pre-processed mode) 1498 1499 ! 1500 !-- open emission data file ( {palmcase}_chemistry ) 1501 1502 CALL open_read_file ( TRIM(input_file_chem) // TRIM(coupling_char), id_emis ) 1503 1504 ! 1505 !-- inquire number of variables 1506 1507 CALL inquire_num_variables ( id_emis, num_vars ) 1508 1509 ! 1510 !-- Get General Dimension Lengths: only # species and # categories. 1511 !-- Tther dimensions depend on the emission mode or specific components 1512 1513 CALL netcdf_data_input_get_dimension_length ( & 1514 id_emis, emt_att%n_emiss_species, 'nspecies' ) 1515 1516 ! 1517 !-- backward compatibility for salsa_mod (ecc) 1518 1519 emt_att%nspec = emt_att%n_emiss_species 1520 1521 ! 1522 !-- Allocate emission values data type arrays 1523 1524 ALLOCATE ( emt(emt_att%n_emiss_species) ) 1525 1526 ! 1527 !-- READING IN SPECIES NAMES 1528 1529 ! 1530 !-- Allocate memory for species names 1531 1532 ALLOCATE ( emt_att%species_name(emt_att%n_emiss_species) ) 1533 1534 ! 1535 !-- Retrieve variable name (again, should use n_emiss_strlen) 1536 1537 CALL get_variable( id_emis, 'emission_name', & 1538 string_values, emt_att%n_emiss_species ) 1539 emt_att%species_name=string_values 1540 1541 ! 1542 !-- dealocate string_values previously allocated in get_variable call 1543 1544 IF ( ALLOCATED(string_values) ) DEALLOCATE (string_values) 1545 1546 ! 1547 !-- READING IN SPECIES INDICES 1548 1549 ! 1550 !-- Allocate memory for species indices 1551 1552 ALLOCATE ( emt_att%species_index(emt_att%n_emiss_species) ) 1553 1554 ! 1555 !-- Retrieve variable data 1556 1557 CALL get_variable( id_emis, 'emission_index', emt_att%species_index ) 1558 ! 1559 !-- Now the routine has to distinguish between chemistry emission 1560 !-- LOD 1 (DEFAULT mode) and LOD 2 (PRE-PROCESSED mode) 1561 1562 ! 1563 !-- START OF EMISSION LOD 1 (DEFAULT MODE) 1564 1565 1566 IF ( emiss_lod == 1 ) THEN 1567 1568 ! for reference (ecc) 1569 ! IF (TRIM(mode_emis) == "DEFAULT" .OR. TRIM(mode_emis) == "default") THEN 1570 1571 ! 1572 !-- get number of emission categories 1573 1574 CALL netcdf_data_input_get_dimension_length ( & 1575 id_emis, emt_att%ncat, 'ncat' ) 1576 1577 !-- READING IN EMISSION CATEGORIES INDICES 1578 1579 ALLOCATE ( emt_att%cat_index(emt_att%ncat) ) 1580 1581 ! 1582 !-- Retrieve variable data 1583 1584 CALL get_variable( id_emis, 'emission_cat_index', emt_att%cat_index ) 1585 1586 1587 ! 1588 !-- Loop through individual species to get basic information on 1589 !-- VOC/PM/NOX/SOX 1590 1591 !------------------------------------------------------------------------------ 1592 !-- NOTE - CHECK ARRAY INDICES FOR READING IN NAMES AND SPECIES 1593 !-- IN LOD1 (DEFAULT MODE) FOR THE VARIOUS MODE SPLITS 1594 !-- AS ALL ID_EMIS CONDITIONALS HAVE BEEN REMOVED FROM GET_VAR 1595 !-- FUNCTIONS. IN THEORY THIS WOULD MEAN ALL ARRAYS SHOULD BE 1596 !-- READ FROM 0 to N-1 (C CONVENTION) AS OPPOSED TO 1 to N 1597 !-- (FORTRAN CONVENTION). KEEP THIS IN MIND !! 1598 !-- (ecc 20190424) 1599 !------------------------------------------------------------------------------ 1457 1600 1458 !-- Allocate emission values data type arrays 1459 ALLOCATE(emt(1:emt_att%nspec)) 1460 1461 1462 !-- Read EMISSION SPECIES NAMES 1463 !Allocate Arrays 1464 ALLOCATE(emt_att%species_name(emt_att%nspec)) 1465 1466 !Call get Variable 1467 CALL get_variable( id_emis, 'emission_name', string_values, emt_att%nspec ) 1468 emt_att%species_name=string_values 1469 ! If allocated, Deallocate var_string, an array only used for reading-in strings 1470 IF (ALLOCATED(string_values)) DEALLOCATE(string_values) 1471 1472 !-- Read EMISSION SPECIES INDEX 1473 !Allocate Arrays 1474 ALLOCATE(emt_att%species_index(emt_att%nspec)) 1475 !Call get Variable 1476 CALL get_variable( id_emis, 'emission_index', emt_att%species_index ) 1477 1478 1479 !-- Now the routine has to distinguish between DEFAULT and PRE-PROCESSED chemistry emission modes 1480 1481 IF (TRIM(mode_emis)=="DEFAULT" .OR. TRIM(mode_emis)=="default") THEN 1601 DO ispec = 1, emt_att%n_emiss_species 1602 1603 ! 1604 !-- VOC DATA (name and composition) 1605 1606 IF ( TRIM(emt_att%species_name(ispec)) == "VOC" .OR. & 1607 TRIM(emt_att%species_name(ispec)) == "voc" ) THEN 1608 1609 ! 1610 !-- VOC name 1611 CALL netcdf_data_input_get_dimension_length ( & 1612 id_emis, emt_att%nvoc, 'nvoc' ) 1613 ALLOCATE ( emt_att%voc_name(emt_att%nvoc) ) 1614 CALL get_variable ( id_emis,"emission_voc_name", & 1615 string_values, emt_att%nvoc ) 1616 emt_att%voc_name = string_values 1617 IF ( ALLOCATED(string_values) ) DEALLOCATE (string_values) 1618 1619 ! 1620 !-- VOC composition 1621 1622 ALLOCATE ( emt_att%voc_comp(emt_att%ncat,emt_att%nvoc) ) 1623 CALL get_variable ( id_emis, "composition_voc", emt_att%voc_comp, & 1624 1, emt_att%ncat, 1, emt_att%nvoc ) 1625 1626 ENDIF ! VOC 1627 1628 ! 1629 !-- PM DATA (name and composition) 1630 1631 IF ( TRIM(emt_att%species_name(ispec)) == "PM" .OR. & 1632 TRIM(emt_att%species_name(ispec)) == "pm") THEN 1633 1634 ! 1635 !-- PM name 1636 1637 CALL netcdf_data_input_get_dimension_length ( & 1638 id_emis, emt_att%npm, 'npm' ) 1639 ALLOCATE ( emt_att%pm_name(emt_att%npm) ) 1640 CALL get_variable ( id_emis, "pm_name", string_values, emt_att%npm ) 1641 emt_att%pm_name = string_values 1642 IF ( ALLOCATED(string_values) ) DEALLOCATE (string_values) 1643 1644 ! 1645 !-- PM composition (PM1, PM2.5 and PM10) 1646 1647 len_dims = 3 ! PM1, PM2.5, PM10 1648 ALLOCATE(emt_att%pm_comp(emt_att%ncat,emt_att%npm,len_dims)) 1649 CALL get_variable ( id_emis, "composition_pm", emt_att%pm_comp, & 1650 1, emt_att%ncat, 1, emt_att%npm, 1, len_dims ) 1651 1652 ENDIF ! PM 1653 1654 ! 1655 !-- NOX (NO and NO2) 1656 1657 IF ( TRIM(emt_att%species_name(ispec)) == "NOX" .OR. & 1658 TRIM(emt_att%species_name(ispec)) == "nox" ) THEN 1659 1660 ALLOCATE ( emt_att%nox_comp(emt_att%ncat,emt_att%nnox) ) 1661 CALL get_variable ( id_emis, "composition_nox", emt_att%nox_comp, & 1662 1, emt_att%ncat, 1, emt_att%nnox ) 1663 1664 ENDIF ! NOX 1665 1666 ! 1667 !-- SOX (SO2 and SO4) 1668 1669 IF ( TRIM(emt_att%species_name(ispec)) == "SOX" .OR. & 1670 TRIM(emt_att%species_name(ispec)) == "sox" ) THEN 1671 1672 ALLOCATE ( emt_att%sox_comp(emt_att%ncat,emt_att%nsox) ) 1673 CALL get_variable ( id_emis, "composition_sox", emt_att%sox_comp, & 1674 1, emt_att%ncat, 1, emt_att%nsox ) 1675 1676 ENDIF ! SOX 1677 1678 ENDDO ! do ispec 1679 1680 ! 1681 !-- EMISSION TIME SCALING FACTORS (hourly and MDH data) 1482 1682 1483 !number of categories 1484 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%ncat, 'ncat' ) 1485 1486 !-- Read EMISSION CATEGORIES INDEX 1487 !Allocate Arrays 1488 ALLOCATE(emt_att%cat_index(emt_att%ncat)) 1489 !Call get Variable 1490 CALL get_variable( id_emis, 'emission_cat_index', emt_att%cat_index ) 1491 1683 ! 1684 !-- HOUR 1685 IF ( TRIM(time_fac_type) == "HOUR" .OR. & 1686 TRIM(time_fac_type) == "hour" ) THEN 1687 1688 CALL netcdf_data_input_get_dimension_length ( & 1689 id_emis, emt_att%nhoursyear, 'nhoursyear' ) 1690 ALLOCATE ( emt_att%hourly_emis_time_factor(emt_att%ncat,emt_att%nhoursyear) ) 1691 CALL get_variable ( id_emis, "emission_time_factors", & 1692 emt_att%hourly_emis_time_factor, & 1693 1, emt_att%ncat, 1, emt_att%nhoursyear ) 1694 1695 ! 1696 !-- MDH 1697 1698 ELSE IF ( TRIM(time_fac_type) == "MDH" .OR. & 1699 TRIM(time_fac_type) == "mdh" ) THEN 1700 1701 CALL netcdf_data_input_get_dimension_length ( & 1702 id_emis, emt_att%nmonthdayhour, 'nmonthdayhour' ) 1703 ALLOCATE ( emt_att%mdh_emis_time_factor(emt_att%ncat,emt_att%nmonthdayhour) ) 1704 CALL get_variable ( id_emis, "emission_time_factors", & 1705 emt_att%mdh_emis_time_factor, & 1706 1, emt_att%ncat, 1, emt_att%nmonthdayhour ) 1707 1708 ! 1709 !-- ERROR (time factor undefined) 1710 1711 ELSE 1712 1713 message_string = 'We are in the DEFAULT chemistry emissions mode: ' // & 1714 ' !no time-factor type specified!' // & 1715 'Please specify the value of time_fac_type:' // & 1716 ' either "MDH" or "HOUR"' 1717 CALL message( 'netcdf_data_input_chemistry_data', 'CM0200', 2, 2, 0, 6, 0 ) 1492 1718 1493 DO ispec=1,emt_att%nspec 1494 !-- EMISSION_VOC_NAME (1-DIMENSIONAL) 1495 IF (TRIM(emt_att%species_name(ispec))=="VOC" .OR. TRIM(emt_att%species_name(ispec))=="voc") THEN 1496 !Allocate Array 1497 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%nvoc, 'nvoc' ) 1498 ALLOCATE(emt_att%voc_name(1:emt_att%nvoc)) 1499 !Read-in Variable 1500 CALL get_variable( id_emis,"emission_voc_name",string_values, emt_att%nvoc) 1501 emt_att%voc_name=string_values 1502 IF (ALLOCATED(string_values)) DEALLOCATE(string_values) 1719 1720 ENDIF ! time_fac_type 1721 1722 ! 1723 !-- read in default (LOD1) emissions from chemisty netCDF file per species 1724 1725 ! 1726 !-- NOTE - at the moment the data is read in per species, but in the future it would 1727 !-- be much more sensible to read in per species per time step to reduce 1728 !-- memory consumption and, to a lesser degree, dimensionality of data exchange 1729 !-- (I expect this will be necessary when the problem size is large) 1730 1731 DO ispec = 1, emt_att%n_emiss_species 1732 1733 ! 1734 !-- allocate space for species specific emission values 1735 !-- NOTE - this array is extended by 1 cell in each horizontal direction 1736 !-- to compensate for an apparent linear offset. The reason of this 1737 !-- offset is not known but it has been determined to take place beyond the 1738 !-- scope of this module, and has little to do with index conventions. 1739 !-- That is, setting the array horizontal limit from nx0:nx1 to 1:(nx1-nx0+1) 1740 !-- or nx0+1:nx1+1 did not result in correct or definite behavior 1741 !-- This must be looked at at some point by the Hannover team but for now 1742 !-- this workaround is deemed reasonable (ecc 20190417) 1743 1744 IF ( .NOT. ALLOCATED ( emt(ispec)%default_emission_data ) ) THEN 1745 ALLOCATE ( emt(ispec)%default_emission_data(emt_att%ncat,nys:nyn+1,nxl:nxr+1) ) 1746 ENDIF 1747 ! 1748 !-- allocate dummy variable w/ index order identical to that shown in the netCDF header 1749 1750 ALLOCATE ( dum_var_5d(1,nys:nyn,nxl:nxr,1,emt_att%ncat) ) 1751 ! 1752 !-- get variable. be very careful 1753 !-- I am using get_variable_5d_real_dynamic (note logical argument at the end) 1754 !-- 1) use Fortran index convention (i.e., 1 to N) 1755 !-- 2) index order must be in reverse order from above allocation order 1503 1756 1504 !-- COMPOSITION VOC (2-DIMENSIONAL) 1505 !Allocate Array 1506 ALLOCATE(emt_att%voc_comp(1:emt_att%ncat,1:emt_att%nvoc)) 1507 !Read-in Variable 1508 ! CALL get_variable(id_emis,"composition_voc",emt%voc_comp,1,1,emt%ncat,emt%nvoc) 1509 CALL get_variable(id_emis,"composition_voc",emt_att%voc_comp,1,emt_att%ncat,1,emt_att%nvoc) 1757 CALL get_variable ( id_emis, "emission_values", dum_var_5d, & 1758 1, ispec, nxl+1, nys+1, 1, & 1759 emt_att%ncat, 1, nxr-nxl+1, nyn-nys+1, emt_att%dt_emission, & 1760 .FALSE. ) 1761 ! 1762 !-- assign temp array to data structure then deallocate temp array 1763 !-- NOTE - indices are shifted from nx0:nx1 to nx0+1:nx1+1 to offset 1764 !-- the emission data array to counter said domain offset 1765 !-- (ecc 20190417) 1766 1767 DO k = 1, emt_att%ncat 1768 DO j = nys+1, nyn+1 1769 DO i = nxl+1, nxr+1 1770 emt(ispec)%default_emission_data(k,j,i) = dum_var_5d(1,j-1,i-1,1,k) 1771 ENDDO 1772 ENDDO 1773 ENDDO 1774 1775 DEALLOCATE ( dum_var_5d ) 1776 1777 ENDDO ! ispec 1778 ! 1779 !-- UNITS 1780 1781 CALL get_attribute(id_emis,"units",emt_att%units,.FALSE.,"emission_values") 1782 1783 ! 1784 !-- END DEFAULT MODE 1785 1786 1787 ! 1788 !-- START LOD 2 (PRE-PROCESSED MODE) 1789 1790 ELSE IF ( emiss_lod == 2 ) THEN 1791 1792 ! for reference (ecc) 1793 ! ELSE IF (TRIM(mode_emis) == "PRE-PROCESSED" .OR. TRIM(mode_emis) == "pre-processed") THEN 1794 1795 ! 1796 !-- For LOD 2 only VOC and emission data need be read 1797 1798 !------------------------------------------------------------------------------ 1799 !-- NOTE - CHECK ARRAY INDICES FOR READING IN NAMES AND SPECIES 1800 !-- IN LOD2 (PRE-PROCESSED MODE) FOR THE VARIOUS MODE SPLITS 1801 !-- AS ALL ID_EMIS CONDITIONALS HAVE BEEN REMOVED FROM GET_VAR 1802 !-- FUNCTIONS. IN THEORY THIS WOULD MEAN ALL ARRAYS SHOULD BE 1803 !-- READ FROM 0 to N-1 (C CONVENTION) AS OPPOSED TO 1 to N 1804 !-- (FORTRAN CONVENTION). KEEP THIS IN MIND !! 1805 !-- (ecc 20190424) 1806 !------------------------------------------------------------------------------ 1807 1808 DO ispec = 1, emt_att%n_emiss_species 1809 1810 ! 1811 !-- VOC DATA (name and composition) 1812 1813 IF ( TRIM(emt_att%species_name(ispec)) == "VOC" .OR. & 1814 TRIM(emt_att%species_name(ispec)) == "voc" ) THEN 1815 1816 ! 1817 !-- VOC name 1818 CALL netcdf_data_input_get_dimension_length ( & 1819 id_emis, emt_att%nvoc, 'nvoc' ) 1820 ALLOCATE ( emt_att%voc_name(emt_att%nvoc) ) 1821 CALL get_variable ( id_emis, "emission_voc_name", & 1822 string_values, emt_att%nvoc) 1823 emt_att%voc_name = string_values 1824 IF ( ALLOCATED(string_values) ) DEALLOCATE (string_values) 1825 1826 ! 1827 !-- VOC composition 1828 1829 ALLOCATE ( emt_att%voc_comp(emt_att%ncat,emt_att%nvoc) ) 1830 CALL get_variable ( id_emis, "composition_voc", emt_att%voc_comp, & 1831 1, emt_att%ncat, 1, emt_att%nvoc ) 1832 ENDIF ! VOC 1833 1834 ENDDO ! ispec 1835 1836 ! 1837 !-- EMISSION DATA 1838 1839 CALL netcdf_data_input_get_dimension_length ( & 1840 id_emis, emt_att%dt_emission, 'time' ) 1841 1842 ! 1843 !-- read in pre-processed (LOD2) emissions from chemisty netCDF file per species 1844 1845 ! 1846 !-- NOTE - at the moment the data is read in per species, but in the future it would 1847 !-- be much more sensible to read in per species per time step to reduce 1848 !-- memory consumption and, to a lesser degree, dimensionality of data exchange 1849 !-- (I expect this will be necessary when the problem size is large) 1850 1851 DO ispec = 1, emt_att%n_emiss_species 1852 1853 ! 1854 !-- allocate space for species specific emission values 1855 !-- NOTE - this array is extended by 1 cell in each horizontal direction 1856 !-- to compensate for an apparent linear offset. The reason of this 1857 !-- offset is not known but it has been determined to take place beyond the 1858 !-- scope of this module, and has little to do with index conventions. 1859 !-- That is, setting the array horizontal limit from nx0:nx1 to 1:(nx1-nx0+1) 1860 !-- or nx0+1:nx1+1 did not result in correct or definite behavior 1861 !-- This must be looked at at some point by the Hannover team but for now 1862 !-- this workaround is deemed reasonable (ecc 20190417) 1863 1864 IF ( .NOT. ALLOCATED( emt(ispec)%preproc_emission_data ) ) THEN 1865 ALLOCATE( emt(ispec)%preproc_emission_data( & 1866 emt_att%dt_emission, 1, nys:nyn+1, nxl:nxr+1) ) 1510 1867 ENDIF 1511 1512 !-- EMISSION_PM_NAME (1-DIMENSIONAL) 1513 IF (TRIM(emt_att%species_name(ispec))=="PM" .OR. TRIM(emt_att%species_name(ispec))=="pm") THEN 1514 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%npm, 'npm' ) 1515 ALLOCATE(emt_att%pm_name(1:emt_att%npm)) 1516 !Read-in Variable 1517 CALL get_variable( id_emis,"pm_name",string_values, emt_att%npm) 1518 emt_att%pm_name=string_values 1519 IF (ALLOCATED(string_values)) DEALLOCATE(string_values) 1520 1521 !-- COMPOSITION PM (3-DIMENSIONAL) 1522 !Allocate 1523 len_dims=3 !> number of PMs: PM1, PM2.5 and PM10 1524 ALLOCATE(emt_att%pm_comp(1:emt_att%ncat,1:emt_att%npm,1:len_dims)) 1525 !Read-in Variable 1526 CALL get_variable(id_emis,"composition_pm",emt_att%pm_comp,1,emt_att%ncat,1,emt_att%npm,1,len_dims) 1527 ENDIF 1528 1529 !-- COMPOSITION_NOX (2-DIMENSIONAL) 1530 IF (TRIM(emt_att%species_name(ispec))=="NOx" .OR. TRIM(emt_att%species_name(ispec))=="nox") THEN 1531 !Allocate array 1532 ALLOCATE(emt_att%nox_comp(1:emt_att%ncat,1:emt_att%nnox)) 1533 !Read-in Variable 1534 CALL get_variable(id_emis,"composition_nox",emt_att%nox_comp,1,emt_att%ncat,1,emt_att%nnox) 1535 ENDIF 1536 1537 !-- COMPOSITION-SOX (2-DIMENSIONAL) 1538 IF (TRIM(emt_att%species_name(ispec))=="SOx" .OR. TRIM(emt_att%species_name(ispec))=="sox") THEN 1539 ALLOCATE(emt_att%sox_comp(1:emt_att%ncat,1:emt_att%nsox)) 1540 !Read-in Variable 1541 CALL get_variable(id_emis,"composition_sox",emt_att%sox_comp,1,emt_att%ncat,1,emt_att%nsox) 1542 ENDIF 1543 ENDDO !>ispec 1544 1545 !-- For reading the emission time factors, the distinction between HOUR and MDH data is necessary 1546 1547 !-- EMISSION_TIME_SCALING_FACTORS 1548 !-- HOUR 1549 IF (TRIM(time_fac_type)=="HOUR" .OR. TRIM(time_fac_type)=="hour") THEN 1550 !-- Allocate Array 1551 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%nhoursyear, 'nhoursyear' ) 1552 ALLOCATE(emt_att%hourly_emis_time_factor(1:emt_att%ncat,1:emt_att%nhoursyear)) 1553 !Read-in Variable 1554 CALL get_variable(id_emis,"emission_time_factors",emt_att%hourly_emis_time_factor,1, & 1555 emt_att%ncat,1,emt_att%nhoursyear) 1556 1557 !-- MDH 1558 ELSE IF (TRIM(time_fac_type) == "MDH" .OR. TRIM(time_fac_type) == "mdh") THEN 1559 !-- Allocate Array 1560 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%nmonthdayhour, 'nmonthdayhour' ) 1561 ALLOCATE(emt_att%mdh_emis_time_factor(1:emt_att%ncat,1:emt_att%nmonthdayhour)) 1562 !-- Read-in Variable 1563 CALL get_variable(id_emis,"emission_time_factors",emt_att%mdh_emis_time_factor,1, & 1564 emt_att%ncat,1,emt_att%nmonthdayhour) 1565 1566 ELSE 1567 1568 message_string = 'We are in the DEFAULT chemistry emissions mode: ' // & 1569 ' !no time-factor type specified!' // & 1570 'Please, specify the value of time_fac_type:' // & 1571 ' either "MDH" or "HOUR"' 1572 CALL message( 'netcdf_data_input_chemistry_data', 'CM0200', 2, 2, 0, 6, 0 ) 1573 1574 1575 ENDIF 1576 1577 !-- Finally read-in the emission values and their units (DEFAULT mode) 1578 1579 DO ispec=1,emt_att%nspec 1580 1581 IF ( .NOT. ALLOCATED( emt(ispec)%default_emission_data ) ) & 1582 ALLOCATE(emt(ispec)%default_emission_data(1:emt_att%ncat,1:ny+1,1:nx+1)) 1583 1584 ALLOCATE(dum_var_3d(1:emt_att%ncat,nys+1:nyn+1,nxl+1:nxr+1)) 1585 1586 CALL get_variable(id_emis,"emission_values",dum_var_3d,ispec,1,emt_att%ncat,nys,nyn,nxl,nxr) 1587 1588 emt(ispec)%default_emission_data(:,nys+1:nyn+1,nxl+1:nxr+1) = & 1589 dum_var_3d(1:emt_att%ncat,nys+1:nyn+1,nxl+1:nxr+1) 1590 1591 DEALLOCATE (dum_var_3d) 1592 1593 ENDDO 1594 1595 !-- UNITS 1596 CALL get_attribute(id_emis,"units",emt_att%units,.FALSE.,"emission_values") 1597 1598 1599 !-- PRE-PROCESSED MODE -- 1600 1601 ELSE IF (TRIM(mode_emis)=="PRE-PROCESSED" .OR. TRIM(mode_emis)=="pre-processed") THEN 1602 !-- In the PRE-PROCESSED mode, only the VOC names, the VOC_composition, the emission values and their units remain to be read at this point 1603 1604 DO ispec=1,emt_att%nspec 1605 1606 !-- EMISSION_VOC_NAME (1-DIMENSIONAL) 1607 IF (TRIM(emt_att%species_name(ispec))=="VOC" .OR. TRIM(emt_att%species_name(ispec))=="voc") THEN 1608 !Allocate Array 1609 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%nvoc, 'nvoc' ) 1610 ALLOCATE(emt_att%voc_name(1:emt_att%nvoc)) 1611 !Read-in Variable 1612 CALL get_variable( id_emis,"emission_voc_name",string_values, emt_att%nvoc) 1613 emt_att%voc_name=string_values 1614 IF (ALLOCATED(string_values)) DEALLOCATE(string_values) 1615 1616 !-- COMPOSITION VOC (2-DIMENSIONAL) 1617 !Allocate Array 1618 ALLOCATE(emt_att%voc_comp(1:emt_att%ncat,1:emt_att%nvoc)) 1619 !Read-in Variable 1620 CALL get_variable(id_emis,"composition_voc",emt_att%voc_comp,1,emt_att%ncat,1,emt_att%nvoc) 1621 ENDIF 1622 1623 ENDDO !> ispec 1624 1625 !-- EMISSION_VALUES (4-DIMENSIONAL) 1626 !Calculate temporal dimension length 1627 CALL netcdf_data_input_get_dimension_length( id_emis, emt_att%dt_emission, 'time' ) 1628 1629 1630 DO ispec=1,emt_att%nspec 1631 1632 !Allocation for the entire domain has to be done only for the first processor between all the subdomains 1633 IF ( .NOT. ALLOCATED( emt(ispec)%preproc_emission_data ) ) & 1634 ALLOCATE(emt(ispec)%preproc_emission_data(emt_att%dt_emission,1,1:ny+1,1:nx+1)) 1635 1636 !> allocate variable where to pass emission values read from netcdf 1637 ALLOCATE(dum_var_4d(1:emt_att%dt_emission,1,nys+1:nyn+1,nxl+1:nxr+1)) 1638 1639 !Read-in Variable 1640 CALL get_variable(id_emis,"emission_values",dum_var_4d,ispec,1,emt_att%dt_emission,1,1,nys,nyn,nxl,nxr) 1641 1642 1643 emt(ispec)%preproc_emission_data(:,1,nys+1:nyn+1,nxl+1:nxr+1) = & 1644 dum_var_4d(1:emt_att%dt_emission,1,nys+1:nyn+1,nxl+1:nxr+1) 1645 1646 DEALLOCATE ( dum_var_4d ) 1647 1648 ENDDO 1649 1650 !-- UNITS 1651 CALL get_attribute(id_emis,"units",emt_att%units,.FALSE.,"emission_values") 1868 ! 1869 !-- allocate dummy variable w/ index order identical to that shown in the netCDF header 1870 1871 ALLOCATE ( dum_var_5d(emt_att%dt_emission,1,nys:nyn,nxl:nxr,1) ) 1872 ! 1873 !-- get variable. be very careful 1874 !-- I am using get_variable_5d_real_dynamic (note logical argument at the end) 1875 !-- 1) use Fortran index convention (i.e., 1 to N) 1876 !-- 2) index order must be in reverse order from above allocation order 1877 1878 CALL get_variable ( id_emis, "emission_values", dum_var_5d, & 1879 ispec, nxl+1, nys+1, 1, 1, & 1880 1, nxr-nxl+1, nyn-nys+1, 1, emt_att%dt_emission, & 1881 .FALSE. ) 1882 ! 1883 !-- assign temp array to data structure then deallocate temp array 1884 !-- NOTE - indices are shifted from nx0:nx1 to nx0+1:nx1+1 to offset 1885 !-- the emission data array to counter said unkonwn offset 1886 !-- (ecc 20190417) 1887 1888 DO k = 1, emt_att%dt_emission 1889 DO j = nys+1, nyn+1 1890 DO i = nxl+1, nxr+1 1891 emt(ispec)%preproc_emission_data(k,1,j,i) = dum_var_5d(k,1,j-1,i-1,1) 1892 ENDDO 1893 ENDDO 1894 ENDDO 1895 1896 DEALLOCATE ( dum_var_5d ) 1897 1898 ENDDO ! ispec 1899 ! 1900 !-- UNITS 1901 1902 CALL get_attribute ( id_emis, "units", emt_att%units, .FALSE. , "emission_values" ) 1652 1903 1653 ENDIF 1654 1655 CALL close_input_file( id_emis)1904 ENDIF ! LOD1 & LOD2 (default and pre-processed mode) 1905 1906 CALL close_input_file (id_emis) 1656 1907 1657 1908 #endif 1658 ENDIF 1909 1910 ENDIF ! LOD0 (parameterized mode) 1659 1911 1660 1912 END SUBROUTINE netcdf_data_input_chemistry_data 1913 1661 1914 1662 1915 !------------------------------------------------------------------------------! … … 5358 5611 ENDIF 5359 5612 5360 5361 !Temporary solution for reading emission chemistry files: TBD: we should discuss whether remove it or not 5362 IF ( id==id_emis ) THEN 5363 5364 !-- Allocate temporary variable according to memory access on file. 5365 ALLOCATE( tmp(is:ie,js:je) ) 5366 5367 !-- Get variable 5368 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5369 start = (/ is, js /), & 5370 count = (/ ie-is+1 , je-js+1 /) ) 5371 5372 var=tmp 5373 5374 CALL handle_error( 'get_variable_2d_real', 530, variable_name ) !TBD: the error number shuld be changed, but since the solution is 5375 ! provisory, we give the same as below 5376 5377 DEALLOCATE( tmp ) 5378 5379 !> Original Subroutine part 5380 ELSE 5381 ! 5382 !-- Allocate temporary variable according to memory access on file. 5383 ALLOCATE( tmp(is:ie,js:je) ) 5384 ! 5385 !-- Get variable 5386 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5387 start = (/ is+1, js+1 /), & 5388 count = (/ ie-is + 1, je-js+1 /) ) 5613 ! 5614 !-- Allocate temporary variable according to memory access on file. 5615 ALLOCATE( tmp(is:ie,js:je) ) 5616 ! 5617 !-- Get variable 5618 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5619 start = (/ is+1, js+1 /), & 5620 count = (/ ie-is + 1, je-js+1 /) ) 5389 5621 CALL handle_error( 'get_variable_2d_real', 530, variable_name ) 5390 5622 ! 5391 !-- 5623 !-- Resort data. Please note, dimension subscripts of var all start at 1. 5392 5624 DO i = is, ie 5393 5625 DO j = js, je … … 5398 5630 DEALLOCATE( tmp ) 5399 5631 5400 ENDIF5401 5632 #endif 5402 5633 END SUBROUTINE get_variable_2d_real … … 5713 5944 ENDIF 5714 5945 5715 !Temporary solution for reading emission chemistry files: 5716 IF ( id==id_emis ) THEN 5717 5718 !-- Allocate temporary variable according to memory access on file. 5719 ALLOCATE( tmp(is:ie,js:je,k1s:k1e,k2s:k2e) ) 5720 5721 !-- Get variable 5722 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5723 start = (/ is, js, k1s+1, k2s+1 /), & 5724 count = (/ ie-is+1 , je-js+1, k1e-k1s+1, k2e-k2s+1 /) ) 5725 5726 var=tmp 5946 ! 5947 !-- Allocate temporary variable according to memory access on file. 5948 ALLOCATE( tmp(is:ie,js:je,k1s:k1e,k2s:k2e) ) 5949 ! 5950 !-- Get variable 5951 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5952 start = (/ is+1, js+1, k1s+1, k2s+1 /), & 5953 count = (/ ie-is+1, je-js+1, k1e-k1s+1, k2e-k2s+1 /) ) 5727 5954 5728 5955 CALL handle_error( 'get_variable_4d_real', 535, variable_name ) 5729 5730 DEALLOCATE( tmp ) 5731 5732 !> Original subroutine part 5733 ELSE 5734 ! 5735 !-- Allocate temporary variable according to memory access on file. 5736 ALLOCATE( tmp(is:ie,js:je,k1s:k1e,k2s:k2e) ) 5737 ! 5738 !-- Get variable 5739 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 5740 start = (/ is+1, js+1, k1s+1, k2s+1 /), & 5741 count = (/ ie-is+1, je-js+1, & 5742 k1e-k1s+1, k2e-k2s+1 /) ) 5743 5744 CALL handle_error( 'get_variable_4d_real', 535, variable_name ) 5745 ! 5746 !-- Resort data. Please note, dimension subscripts of var all start at 1. 5747 DO i = is, ie 5748 DO j = js, je 5749 DO k1 = k1s, k1e 5750 DO k2 = k2s, k2e 5751 var(k2-k2s+1,k1-k1s+1,j-js+1,i-is+1) = tmp(i,j,k1,k2) 5752 ENDDO 5956 ! 5957 !-- Resort data. Please note, dimension subscripts of var all start at 1. 5958 DO i = is, ie 5959 DO j = js, je 5960 DO k1 = k1s, k1e 5961 DO k2 = k2s, k2e 5962 var(k2-k2s+1,k1-k1s+1,j-js+1,i-is+1) = tmp(i,j,k1,k2) 5753 5963 ENDDO 5754 5964 ENDDO 5755 5965 ENDDO 5756 5757 DEALLOCATE( tmp ) 5758 ENDIF 5966 ENDDO 5967 5968 DEALLOCATE( tmp ) 5969 5759 5970 #endif 5971 5760 5972 END SUBROUTINE get_variable_4d_real 5761 5973 … … 5806 6018 5807 6019 !Temporary solution for reading emission chemistry files: 5808 IF ( id ==id_emis ) THEN6020 IF ( id == id_emis ) THEN 5809 6021 5810 6022 !-- Allocate temporary variable according to memory access on file. … … 5993 6205 5994 6206 !Temporary solution for reading emission chemistry files: 5995 IF ( id ==id_emis ) THEN6207 IF ( id == id_emis ) THEN 5996 6208 5997 6209 !-- Allocate temporary variable according to memory access on file. … … 6040 6252 END SUBROUTINE get_variable_5d_to_4d_real 6041 6253 6254 6255 !------------------------------------------------------------------------------! 6256 ! Description: 6257 ! ------------ 6258 !> Reads a 5D float variable from file. 6259 !> NOTE - This subroutine is used specific for reading NC variable 6260 !> emission_values having a "z" dimension. Said dimension 6261 !> is to be removed in the future and this subroutine shall 6262 !> be depreciated accordingly (ecc 20190418) 6263 !------------------------------------------------------------------------------! 6264 SUBROUTINE get_variable_5d_real( id, variable_name, var, is, ie, js, je, & 6265 k1s, k1e, k2s, k2e, k3s, k3e ) 6266 6267 USE indices 6268 USE pegrid 6269 6270 IMPLICIT NONE 6271 6272 CHARACTER(LEN=*) :: variable_name !< variable name 6273 6274 INTEGER(iwp) :: i !< i index 6275 INTEGER(iwp) :: ie !< i index start 6276 INTEGER(iwp) :: is !< i index end 6277 INTEGER(iwp) :: id_var !< netCDF variable ID (varid) 6278 INTEGER(iwp) :: j !< j index 6279 INTEGER(iwp) :: je !< j index start 6280 INTEGER(iwp) :: js !< j index end 6281 INTEGER(iwp) :: k1 !< k1 index 6282 INTEGER(iwp) :: k1e !< k1 index start 6283 INTEGER(iwp) :: k1s !< k1 index end 6284 INTEGER(iwp) :: k2 !< k2 index 6285 INTEGER(iwp) :: k2e !< k2 index start 6286 INTEGER(iwp) :: k2s !< k2 index end 6287 INTEGER(iwp) :: k3 !< k3 index 6288 INTEGER(iwp) :: k3e !< k3 index start 6289 INTEGER(iwp) :: k3s !< k3 index end 6290 INTEGER(iwp), INTENT(IN) :: id !< netCDF file ID (ncid) 6291 6292 REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: tmp !< temp array to read data from file 6293 REAL(wp), DIMENSION(:,:,:,:,:), INTENT(INOUT) :: var !< variable to be read 6294 6295 #if defined( __netcdf ) 6296 6297 ! 6298 !-- Inquire variable id 6299 6300 nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var ) 6301 6302 ! 6303 !-- Check for collective read-operation and set respective NetCDF flags if required. 6304 6305 IF ( collective_read ) THEN 6306 6307 #if defined( __netcdf4_parallel ) 6308 nc_stat = NF90_VAR_PAR_ACCESS (id, id_var, NF90_COLLECTIVE) 6309 #endif 6310 6311 ENDIF 6312 6313 ! 6314 !-- Allocate temporary variable according to memory access on file. 6315 6316 ALLOCATE( tmp(is:ie,js:je,k1s:k1e,k2s:k2e,k3s:k3e) ) 6317 6318 ! 6319 !-- Get variable from file 6320 6321 nc_stat = NF90_GET_VAR ( id, id_var, tmp, & 6322 start = (/ is+1, js+1, k1s+1, k2s+1, k3s+1 /), & 6323 count = (/ ie-is+1, je-js+1, k1e-k1s+1, k2e-k2s+1, k3e-k3s+1 /) ) 6324 6325 CALL handle_error( 'get_variable_5d_real', 535, variable_name ) 6326 6327 ! 6328 !-- Resort (reverse index order) and standardize (from 1 to N) output array 6329 6330 DO i = is, ie 6331 DO j = js, je 6332 DO k1 = k1s, k1e 6333 DO k2 = k2s, k2e 6334 DO k3 = k3s, k3e 6335 var(k3-k3s+1,k2-k2s+1,k1-k1s+1,j-js+1,i-is+1) = tmp(i,j,k1,k2,k3) 6336 ENDDO 6337 ENDDO 6338 ENDDO 6339 ENDDO 6340 ENDDO 6341 6342 DEALLOCATE( tmp ) 6343 6344 #endif 6345 6346 END SUBROUTINE get_variable_5d_real 6347 6348 6349 !------------------------------------------------------------------------------! 6350 ! Description: 6351 ! ------------ 6352 !> Reads a 5D float variables from dynamic driver, such as time-dependent xy-, 6353 !> xz- or yz-boundary data as well as 5D initialization data. Please note, 6354 !> the passed arguments are start indices and number of elements in each 6355 !> dimension, which is in contrast to the other 3d versions where start- and 6356 !> end indices are passed. The different handling of 5D dynamic variables is 6357 !> due to its asymmetry for the u- and v component. 6358 !> NOTE(1) - This subroutine is more flexible than get_variable_xd_real as it 6359 !> provides much better control over starting and count indices 6360 !> (ecc 20190418) 6361 !> NOTE(2) - This subroutine is used specific for reading NC variable 6362 !> emission_values having a "z" dimension. Said dimension 6363 !> is to be removed in the future and this subroutine shall 6364 !> be depreciated accordingly (ecc 20190418) 6365 !------------------------------------------------------------------------------! 6366 6367 SUBROUTINE get_variable_5d_real_dynamic( id, variable_name, var, & 6368 i1s, i2s, i3s, i4s, i5s, & 6369 count_1, count_2, count_3, count_4, count_5, & 6370 par_access ) 6371 6372 USE indices 6373 USE pegrid 6374 6375 IMPLICIT NONE 6376 6377 CHARACTER(LEN=*) :: variable_name !< variable name 6378 6379 LOGICAL :: par_access !< additional flag indicating parallel read 6380 6381 INTEGER(iwp) :: count_1 !< # elements read in dimension 1 wrt file 6382 INTEGER(iwp) :: count_2 !< # elements read in dimension 2 wrt file 6383 INTEGER(iwp) :: count_3 !< # elements read in dimension 3 wrt file 6384 INTEGER(iwp) :: count_4 !< # elements read in dimension 4 wrt file 6385 INTEGER(iwp) :: count_5 !< # elements read in dimension 5 wrt file 6386 INTEGER(iwp) :: i1 !< index for dimension 1 on file 6387 INTEGER(iwp) :: i1s !< starting index for dimension 1 hyperslab 6388 INTEGER(iwp) :: i2 !< index for dimension 2 on file 6389 INTEGER(iwp) :: i2s !< starting index for dimension 2 hyperslab 6390 INTEGER(iwp) :: i3 !< index for dimension 3 on file 6391 INTEGER(iwp) :: i3s !< starting index for dimension 3 hyperslab 6392 INTEGER(iwp) :: i4 !< index for dimension 4 on file 6393 INTEGER(iwp) :: i4s !< starting index for dimension 4 hyperslab 6394 INTEGER(iwp) :: i5 !< index for dimension 5 on file 6395 INTEGER(iwp) :: i5s !< starting index for dimension 5 hyperslab 6396 INTEGER(iwp) :: id_var !< netCDF variable id (varid) 6397 INTEGER(iwp) :: lb1 !< lower bound of dimension 1 wrt file 6398 INTEGER(iwp) :: lb2 !< lower bound of dimension 2 wrt file 6399 INTEGER(iwp) :: lb3 !< lower bound of dimension 3 wrt file 6400 INTEGER(iwp) :: lb4 !< lower bound of dimension 4 wrt file 6401 INTEGER(iwp) :: lb5 !< lower bound of dimension 5 wrt file 6402 INTEGER(iwp) :: ub1 !< upper bound of dimension 1 wrt file 6403 INTEGER(iwp) :: ub2 !< upper bound of dimension 2 wrt file 6404 INTEGER(iwp) :: ub3 !< upper bound of dimension 3 wrt file 6405 INTEGER(iwp) :: ub4 !< upper bound of dimension 4 wrt file 6406 INTEGER(iwp) :: ub5 !< upper bound of dimension 5 wrt file 6407 INTEGER(iwp), INTENT(IN) :: id !< netCDF file id (ncid) 6408 6409 REAL(wp), DIMENSION(:,:,:,:,:), ALLOCATABLE :: tmp !< temporary variable to read data 6410 !< from file according is reverse 6411 !< array index order 6412 REAL(wp), DIMENSION(:,:,:,:,:), INTENT(INOUT) :: var !< input variable 6413 6414 #if defined( __netcdf ) 6415 6416 ! 6417 !-- Inquire variable id. 6418 6419 nc_stat = NF90_INQ_VARID( id, TRIM( variable_name ), id_var ) 6420 6421 ! 6422 !-- Check for collective read-operation and set respective NetCDF flags if required. 6423 !-- Please note, in contrast to the other input routines where each PEs 6424 !-- reads its subdomain data, dynamic input data not by all PEs, only 6425 !-- by those which encompass lateral model boundaries. Hence, collective 6426 !-- read operations are only enabled for top-boundary data. 6427 6428 IF ( collective_read .AND. par_access ) THEN 6429 6430 #if defined( __netcdf4_parallel ) 6431 nc_stat = NF90_VAR_PAR_ACCESS (id, id_var, NF90_COLLECTIVE) 6432 #endif 6433 6434 ENDIF 6435 6436 ! 6437 !-- Allocate temporary variable according to memory access on file. 6438 !-- Therefore, determine dimension bounds of input array. 6439 6440 lb1 = LBOUND(var,5) 6441 ub1 = UBOUND(var,5) 6442 lb2 = LBOUND(var,4) 6443 ub2 = UBOUND(var,4) 6444 lb3 = LBOUND(var,3) 6445 ub3 = UBOUND(var,3) 6446 lb4 = LBOUND(var,2) 6447 ub4 = UBOUND(var,2) 6448 lb5 = LBOUND(var,1) 6449 ub5 = UBOUND(var,1) 6450 ALLOCATE ( tmp(lb1:ub1,lb2:ub2,lb3:ub3,lb4:ub4,lb5:ub5) ) 6451 6452 ! 6453 !-- Get variable 6454 6455 nc_stat = NF90_GET_VAR( id, id_var, tmp, & 6456 start = (/ i1s, i2s, i3s, i4s, i5s /), & 6457 count = (/ count_1, count_2, count_3, count_4, count_5 /) ) 6458 6459 CALL handle_error( 'get_variable_3d_real_dynamic', 537, variable_name ) 6460 6461 ! 6462 !-- Assign temp array to output. Note reverse index order 6463 6464 DO i5 = lb5, ub5 6465 DO i4 = lb4, ub4 6466 DO i3 = lb3, ub3 6467 DO i2 = lb2, ub2 6468 DO i1 = lb1, ub1 6469 var(i5,i4,i3,i2,i1) = tmp(i1,i2,i3,i4,i5) 6470 ENDDO 6471 ENDDO 6472 ENDDO 6473 ENDDO 6474 ENDDO 6475 6476 DEALLOCATE( tmp ) 6477 6478 #endif 6479 6480 END SUBROUTINE get_variable_5d_real_dynamic 6481 6042 6482 6043 6483 !------------------------------------------------------------------------------! -
palm/trunk/SOURCE/time_integration.f90
r3929 r3968 25 25 ! ----------------- 26 26 ! $Id$ 27 ! replace nspec_out with n_matched_vars 28 ! 29 ! 3929 2019-04-24 12:52:08Z banzhafs 27 30 ! Reverse changes back from revision 3878: use chem_boundary_conds instead of 28 31 ! chem_boundary_conds_decycle … … 518 521 519 522 USE chem_modules, & 520 ONLY: bc_cs_t_val, chem_species, cs_name, emissions_anthropogenic, n spec_out523 ONLY: bc_cs_t_val, chem_species, cs_name, emissions_anthropogenic, n_matched_vars 521 524 522 525 USE chemistry_model_mod, & … … 1448 1451 !-- Call emission routine only once an hour 1449 1452 IF (hour_of_year .GT. hour_call_emis ) THEN 1450 CALL chem_emissions_setup( chem_emis_att, chem_emis, n spec_out)1453 CALL chem_emissions_setup( chem_emis_att, chem_emis, n_matched_vars ) 1451 1454 hour_call_emis = hour_of_year 1452 1455 ENDIF
Note: See TracChangeset
for help on using the changeset viewer.