| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034 |
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !-----------------------------------------------------------------------
- ! CVS m_SpatialIntegral.F90,v 1.22 2008-05-12 01:59:33 jacob Exp
- ! CVS MCT_2_8_0
- !BOP -------------------------------------------------------------------
- !
- ! !MODULE: m_SpatialIntegral - Spatial Integrals and Averages using a GeneralGrid
- !
- ! !DESCRIPTION: This module provides spatial integration and averaging
- ! services for the MCT. For a field $\Phi$ sampled at a point ${\bf x}$
- ! in some multidimensional domain $\Omega$, the integral $I$ of
- ! $\Phi({\bf x})$ is
- ! $$ I = \int_{\Omega} \Phi ({\bf x}) d\Omega .$$
- ! The spatial average $A$ of $\Phi({\bf x})$ over $\Omega$ is
- ! $$ A = {{ \int_{\Omega} \Phi ({\bf x}) d\Omega} \over
- ! { \int_{\Omega} d\Omega} }. $$
- ! Since the {\tt AttrVect} represents a discretized field, the integrals
- ! above are implemented as:
- ! $$ I = \sum_{i=1}^N \Phi_i \Delta \Omega_i $$
- ! and
- ! $$ A = {{\sum_{i=1}^N \Phi_i \Delta \Omega_i } \over
- !{\sum_{i=1}^N \Delta \Omega_i } }, $$
- ! where $N$ is the number of physical locations, $\Phi_i$ is the value
- ! of the field $\Phi$ at location $i$, and $\Delta \Omega_i$ is the spatial
- ! weight (lenghth element, cross-sectional area element, volume element,
- ! {\em et cetera}) at location $i$.
- !
- ! MCT extends the concept of integrals and area/volume averages to include
- ! {\em masked} integrals and averages. MCT recognizes both {\em integer}
- ! and {\em real} masks. An integer mask $M$ is a vector of integers (one
- ! corresponding to each physical location) with each element having value
- ! either zero or one. Integer masks are used to include/exclude data from
- ! averages or integrals. For example, if one were to compute globally
- ! averaged cloud amount over land (but not ocean nor sea-ice), one would
- ! assign a $1$ to each location on the land and a $0$ to each non-land
- ! location. A {\em real} mask $F$ is a vector of real numbers (one corresponding
- ! to each physical location) with each element having value within the
- ! closed interval $[0,1]$. .Real masks are used to represent fractional
- ! area/volume coverage at a location by a given component model. For
- ! example, if one wishes to compute area averages over sea-ice, one must
- ! include the ice fraction present at each point. Masked Integrals and
- ! averages are represented in the MCT by:
- ! $$ I = \sum_{i=1}^N {\prod_{j=1}^J M_i} {\prod_{k=1}^K F_i}
- ! \Phi_i \Delta \Omega_i $$
- ! and
- ! $$ A = {{\sum_{i=1}^N \bigg({\prod_{j=1}^J M_i}\bigg) \bigg( {\prod_{k=1}^K F_i}
- ! \bigg) \Phi_i
- ! \Delta \Omega_i } \over
- !{\sum_{i=1}^N \bigg({\prod_{j=1}^J M_i}\bigg) \bigg( {\prod_{k=1}^K F_i} \bigg)
- ! \Delta \Omega_i } }, $$
- ! where $J$ is the number of integer masks and $K$ is the number of real masks.
- !
- ! All of the routines in this module assume field data is stored in an
- ! attribute vector ({\tt AttrVect}), and the integration/averaging is performed
- ! only on the {\tt REAL} attributes. Physical coordinate grid and mask
- ! information is assumed to be stored as attributes in either a
- ! {\tt GeneralGrid}, or pre-combined into a single integer mask and a single
- ! real mask.
- !
- ! !INTERFACE:
- module m_SpatialIntegral
-
- implicit none
- private ! except
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: SpatialIntegral ! Spatial Integral
- public :: SpatialAverage ! Spatial Area Average
- public :: MaskedSpatialIntegral ! Masked Spatial Integral
- public :: MaskedSpatialAverage ! MaskedSpatial Area Average
- public :: PairedSpatialIntegrals ! A Pair of Spatial
- ! Integrals
- public :: PairedSpatialAverages ! A Pair of Spatial
- ! Area Averages
- public :: PairedMaskedSpatialIntegrals ! A Pair of Masked
- ! Spatial Integrals
- public :: PairedMaskedSpatialAverages ! A Pair of Masked
- ! Spatial Area Averages
- interface SpatialIntegral ; module procedure &
- SpatialIntegralRAttrGG_
- end interface
- interface SpatialAverage ; module procedure &
- SpatialAverageRAttrGG_
- end interface
- interface MaskedSpatialIntegral ; module procedure &
- MaskedSpatialIntegralRAttrGG_
- end interface
- interface MaskedSpatialAverage ; module procedure &
- MaskedSpatialAverageRAttrGG_
- end interface
- interface PairedSpatialIntegrals ; module procedure &
- PairedSpatialIntegralRAttrGG_
- end interface
- interface PairedSpatialAverages ; module procedure &
- PairedSpatialAverageRAttrGG_
- end interface
- interface PairedMaskedSpatialIntegrals ; module procedure &
- PairedMaskedIntegralRAttrGG_
- end interface
- interface PairedMaskedSpatialAverages ; module procedure &
- PairedMaskedAverageRAttrGG_
- end interface
- ! !REVISION HISTORY:
- ! 25Oct01 - J.W. Larson <larson@mcs.anl.gov> - Initial version
- ! 9May02 - J.W. Larson <larson@mcs.anl.gov> - Massive Refactoring.
- ! 10-14Jun02 - J.W. Larson <larson@mcs.anl.gov> - Added Masked methods.
- ! 17-18Jun02 - J.W. Larson <larson@mcs.anl.gov> - Added Paired/Masked
- ! methods.
- ! 18Jun02 - J.W. Larson <larson@mcs.anl.gov> - Renamed module from
- ! m_GlobalIntegral to m_SpatialIntegral.
- ! 15Jan03 - E.T. Ong <eong@mcs.anl.gov> - Initialized real-only
- ! AttrVects using nullfied integer lists. This circuitous
- ! hack was required because the compaq compiler does not
- ! compile the function AttrVectExportListToChar.
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname='MCT::m_SpatialIntegral'
- contains
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: SpatialIntegralRAttrGG_ - Compute spatial integral.
- !
- ! !DESCRIPTION:
- ! This routine computes spatial integrals of the {\tt REAL} attributes
- ! of the {\tt REAL} attributes of the input {\tt AttrVect} argument
- ! {\tt inAv}. {\tt SpatialIntegralRAttrGG\_()} takes the input
- ! {\tt AttrVect} argument {\tt inAv} and computes the spatial
- ! integral using weights stored in the {\tt GeneralGrid} argument
- ! {\tt GGrid} and identified by the {\tt CHARACTER} tag {\tt WeightTag}.
- ! The integral of each {\tt REAL} attribute is returned in the output
- ! {\tt AttrVect} argument {\tt outAv}. If {\tt SpatialIntegralRAttrGG\_()}
- ! is invoked with the optional {\tt LOGICAL} input argument
- ! {\tt SumWeights} set as {\tt .TRUE.}, then the weights are also summed
- ! and stored in {\tt outAv} (and can be referenced with the attribute
- ! tag defined by the argument{\tt WeightTag}. If
- ! {\tt SpatialIntegralRAttrGG\_()} is invoked with the optional {\tt INTEGER}
- ! argument {\tt comm} (a Fortran MPI communicator handle), the summation
- ! operations for the integral are completed on the local process, then
- ! reduced across the communicator, with all processes receiving the result.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv}
- ! and the {\tt GeneralGrid} {\tt GGrid} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv} and the point weights stored in {\tt GGrid}.
- !
- ! {\bf N.B.: } If {\tt SpatialIntegralRAttrGG\_()} is invoked with the
- ! optional {\tt LOGICAL} input argument {\tt SumWeights} set as {\tt .TRUE.},
- ! then the value of {\tt WeightTag} must not conflict with any of the
- ! {\tt REAL} attribute tags in {\tt inAv}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} argument {\tt outAv} is an
- ! allocated data structure. The user must deallocate it using the routine
- ! {\tt AttrVect\_clean()} when it is no longer needed. Failure to do so
- ! will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine SpatialIntegralRAttrGG_(inAv, outAv, GGrid, WeightTag, &
- SumWeights, comm)
- ! ! USES:
- use m_stdio
- use m_die
- use m_mpif90
- use m_realkinds, only : FP
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_SpatialIntegralV, only: SpatialIntegralV
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv
- type(GeneralGrid), intent(IN) :: GGrid
- character(len=*), intent(IN) :: WeightTag
- logical, optional, intent(IN) :: SumWeights
- integer, optional, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv
- ! !REVISION HISTORY:
- ! 06Feb02 - J.W. Larson <larson@mcs.anl.gov> - initial version
- ! 09May02 - J.W. Larson <larson@mcs.anl.gov> - Refactored and
- ! renamed SpatialIntegralRAttrGG_().
- ! 07Jun02 - J.W. Larson <larson@mcs.anl.gov> - Bug fix and further
- ! refactoring.
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::SpatialIntegralRAttrGG_'
- integer :: ierr, length
- logical :: mySumWeights
- real(FP), dimension(:), pointer :: gridWeights
- ! Argument Validity Checks
- if(AttrVect_lsize(inAv) /= GeneralGrid_lsize(GGrid)) then
- ierr = AttrVect_lsize(inAv) - GeneralGrid_lsize(GGrid)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv / GGrid length mismatch: ', &
- ' AttrVect_lsize(inAv) = ',AttrVect_lsize(inAv), &
- ' GeneralGrid_lsize(GGrid) = ',GeneralGrid_lsize(GGrid)
- call die(myname_)
- endif
- if(present(SumWeights)) then
- mySumWeights = SumWeights
- else
- mySumWeights = .FALSE.
- endif
- ! ensure unambiguous pointer association status for gridWeights
- nullify(gridWeights)
- ! Extract Grid Weights
- call GeneralGrid_exportRAttr(GGrid, WeightTag, gridWeights, length)
- !
- if(present(comm)) then ! do a distributed AllReduce-style integral:
- call SpatialIntegralV(inAv, outAv, gridWeights, mySumWeights, &
- WeightTag, comm)
- else
- call SpatialIntegralV(inAv, outAv, gridWeights, mySumWeights, &
- WeightTag)
- endif
- ! Clean up temporary allocated space
- deallocate(gridWeights, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: deallocate(gridWeights...failed. ierr=', ierr
- call die(myname_)
- endif
- end subroutine SpatialIntegralRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: SpatialAverageRAttrGG_ - Compute spatial average.
- !
- ! !DESCRIPTION:
- ! This routine computes spatial averages of the {\tt REAL} attributes
- ! of the input {\tt AttrVect} argument {\tt inAv}.
- ! {\tt SpatialAverageRAttrGG\_()} takes the input {\tt AttrVect} argument
- ! {\tt inAv} and computes the spatial average using weights
- ! stored in the {\tt GeneralGrid} argument {\tt GGrid} and identified by
- ! the {\tt CHARACTER} tag {\tt WeightTag}. The average of each {\tt REAL}
- ! attribute is returned in the output {\tt AttrVect} argument {\tt outAv}.
- ! If {\tt SpatialAverageRAttrGG\_()} is invoked with the optional {\tt INTEGER}
- ! argument {\tt comm} (a Fortran MPI communicator handle), the summation
- ! operations for the average are completed on the local process, then
- ! reduced across the communicator, with all processes receiving the result.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv}
- ! and the {\tt GeneralGrid} {\tt GGrid} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv} and the point weights stored in {\tt GGrid}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} argument {\tt outAv} is an
- ! allocated data structure. The user must deallocate it using the routine
- ! {\tt AttrVect\_clean()} when it is no longer needed. Failure to do so
- ! will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine SpatialAverageRAttrGG_(inAv, outAv, GGrid, WeightTag, comm)
- ! ! USES:
- use m_realkinds, only : FP
-
- use m_stdio
- use m_die
- use m_mpif90
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_init => init
- use m_AttrVect, only : AttrVect_zero => zero
- use m_AttrVect, only : AttrVect_clean => clean
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_AttrVect, only : AttrVect_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid
- use m_List, only : List
- use m_List, only : List_nullify => nullify
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv
- type(GeneralGrid), intent(IN) :: GGrid
- character(len=*), intent(IN) :: WeightTag
- integer, optional, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv
- ! !REVISION HISTORY:
- ! 08Feb02 - J.W. Larson <larson@mcs.anl.gov> - initial version
- ! 08May02 - J.W. Larson <larson@mcs.anl.gov> - minor modifications:
- ! 1) renamed the routine to GlobalAverageRAttrGG_
- ! 2) changed calls to reflect new routine name
- ! GlobalIntegralRAttrGG_().
- ! 18Jun02 - J.W. Larson <larson@mcs.anl.gov> - Renamed routine to
- ! SpatialAverageRAttrGG_().
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::SpatialAverageRAtttrGG_'
- type(AttrVect) :: integratedAv
- type(List) :: nullIList
- integer :: i, ierr, iweight
- ! Compute the spatial integral:
- if(present(comm)) then
- call SpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, WeightTag, &
- .TRUE., comm)
- else
- call SpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, WeightTag, &
- .TRUE.)
- endif
- ! Check value of summed weights (to avoid division by zero):
- iweight = AttrVect_indexRA(integratedAv, WeightTag)
- if(integratedAv%rAttr(iweight, 1) == 0._FP) then
- write(stderr,'(2a)') myname_, &
- '::ERROR--Global sum of grid weights is zero.'
- call die(myname_)
- endif
- ! Initialize output AttrVect outAv:
- call List_nullify(nullIList)
- call AttrVect_init(outAv, iList=nullIList, rList=inAv%rList, lsize=1)
- call AttrVect_zero(outAv)
- ! Divide by global weight sum to compute spatial averages from
- ! spatial integrals.
- do i=1,AttrVect_nRAttr(outAv)
- outAv%rAttr(i,1) = integratedAv%rAttr(i,1) &
- / integratedAv%rAttr(iweight,1)
- end do
- ! Clean up temporary AttrVect:
- call AttrVect_clean(integratedAv)
- end subroutine SpatialAverageRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: MaskedSpatialIntegralRAttrGG_ - Masked spatial integral.
- !
- ! !DESCRIPTION:
- ! This routine computes masked spatial integrals of the {\tt REAL}
- ! attributes of the input {\tt AttrVect} argument {\tt inAv}, returning
- ! the masked integrals in the output {\tt AttrVect} {\tt outAv}. All of
- ! the masking data are assumed stored in the input {\tt GeneralGrid}
- ! argument {\tt GGrid}. If integer masks are to be used, their integer
- ! attribute names in {\tt GGrid} are named as a colon-delimited list
- ! in the optional {\tt CHARACTER} input argument {\tt iMaskTags}. Real
- ! masks (if desired) are referenced by their real attribute names in
- ! {\tt GGrid} are named as a colon-delimited list in the optional
- ! {\tt CHARACTER} input argument {\tt rMaskTags}. The user specifies
- ! a choice of mask combination method with the input {\tt LOGICAL} argument
- ! {\tt UseFastMethod}. If ${\tt UseFastMethod} = {\tt .FALSE.}$ this
- ! routine checks each mask entry to ensure that the integer masks contain
- ! only ones and zeroes, and that entries in the real masks are all in
- ! the closed interval $[0,1]$. If ${\tt UseFastMethod} = {\tt .TRUE.}$,
- ! this routine performs direct products of the masks, assuming that the
- ! user has validated them in advance. The optional {\tt LOGICAL} input
- ! argument {\tt SumWeights} determines whether the masked sum of the spatial
- ! weights is computed and returned in {\tt outAv} with the real attribute
- ! name supplied in the optional {\tt CHARACTER} input argument
- ! {\tt WeightSumTag}. This integral can either be a local (i.e. a global
- ! memory space operation), or a global distributed integral. The latter
- ! is the case if the optional input {\tt INTEGER} argument {\tt comm} is
- ! supplied (which corresponds to a Fortran MPI communicatior handle).
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv}
- ! and the input {\tt GeneralGrid} {\tt GGrid} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv} and the point weights stored in {\tt GGrid}.
- !
- ! {\bf N.B.: } If {\tt SpatialIntegralRAttrV\_()} is invoked with the
- ! optional {\tt LOGICAL} input argument {\tt SumWeights} set as {\tt .TRUE.}.
- ! In this case, the none of {\tt REAL} attribute tags in {\tt inAv} may be
- ! named the same as the string contained in {\tt WeightSumTag}, which is an
- ! attribute name reserved for the sum of the weights in the output {\tt AttrVect}
- ! {\tt outAv}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} argument {\tt outAv} is an
- ! allocated data structure. The user must deallocate it using the routine
- ! {\tt AttrVect\_clean()} when it is no longer needed. Failure to do so
- ! will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine MaskedSpatialIntegralRAttrGG_(inAv, outAv, GGrid, SpatialWeightTag, &
- iMaskTags, rMaskTags, UseFastMethod, &
- SumWeights, WeightSumTag, comm)
- ! ! USES:
- use m_stdio
- use m_die
- use m_mpif90
- use m_realkinds, only : FP
- use m_String, only : String
- use m_String, only : String_toChar => toChar
- use m_String, only : String_clean => clean
- use m_List, only : List
- use m_List, only : List_init => init
- use m_List, only : List_clean => clean
- use m_List, only : List_nitem => nitem
- use m_List, only : List_get => get
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportIAttr => exportIAttr
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_AttrVectReduce, only : AttrVect_GlobalWeightedSumRAttr => &
- GlobalWeightedSumRAttr
- use m_AttrVectReduce, only : AttrVect_LocalWeightedSumRAttr => &
- LocalWeightedSumRAttr
- use m_SpatialIntegralV, only : MaskedSpatialIntegralV
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv
- type(GeneralGrid), intent(IN) :: GGrid
- character(len=*), intent(IN) :: SpatialWeightTag
- character(len=*), optional, intent(IN) :: iMaskTags
- character(len=*), optional, intent(IN) :: rMaskTags
- logical, intent(IN) :: UseFastMethod
- logical, optional, intent(IN) :: SumWeights
- character(len=*), optional, intent(IN) :: WeightSumTag
- integer, optional, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv
- ! !REVISION HISTORY:
- ! 11Jun02 - J.W. Larson <larson@mcs.anl.gov> - initial version
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::MaskedSpatialIntegralRAttrGG_'
- integer :: i, ierr, j, length
- logical :: mySumWeights
- type(List) :: iMaskList, rMaskList
- type(String) :: DummStr
- integer, dimension(:), pointer :: iMask, iMaskTemp
- real(FP), dimension(:), pointer :: rMask, rMaskTemp
- integer :: TempMaskLength
- real(FP), dimension(:), pointer :: SpatialWeights
- integer :: niM, nrM ! Number of iMasks and rMasks, respectively
- ! Argument Validity Checks
- if(AttrVect_lsize(inAv) /= GeneralGrid_lsize(GGrid)) then
- ierr = AttrVect_lsize(inAv) - GeneralGrid_lsize(GGrid)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv / GGrid length mismatch: ', &
- ' AttrVect_lsize(inAv) = ',AttrVect_lsize(inAv), &
- ' GeneralGrid_lsize(GGrid) = ',GeneralGrid_lsize(GGrid)
- call die(myname_)
- endif
- if(present(SumWeights)) then
- mySumWeights = SumWeights
- if(.not. present(WeightSumTag)) then
- write(stderr,'(3a)') myname_,':: FATAL--If the input argument SumWeights=.TRUE.,', &
- ' then the argument WeightSumTag must be provided.'
- call die(myname_)
- endif
- else
- mySumWeights = .FALSE.
- endif
- if(present(iMaskTags)) then
- call List_init(iMaskList, iMaskTags)
- if(List_nitem(iMaskList) == 0) then
- write(stderr,'(3a)') myname_,':: ERROR--an INTEGER mask list with', &
- 'no valid items was provided.'
- call die(myname_)
- endif
- endif
- if(present(rMaskTags)) then
- call List_init(rMaskList, rMaskTags)
- if(List_nitem(iMaskList) == 0) then
- write(stderr,'(3a)') myname_,':: ERROR--an REAL mask list with', &
- 'no valid items was provided.'
- call die(myname_)
- endif
- endif
- ! Determine the on-processor vector length for use throughout
- ! this routine:
- length = AttrVect_lsize(inAv)
- !==========================================================
- ! Extract Spatial Weights from GGrid using SpatialWeightTag
- !==========================================================
- nullify(SpatialWeights)
- call GeneralGrid_exportRAttr(GGrid, SpatialWeightTag, SpatialWeights, &
- TempMaskLength)
- if(TempMaskLength /= length) then
- write(stderr,'(3a,i8,a,i8)') myname_,&
- ':: error on return from GeneralGrid_exportRAttr().' , &
- 'Returned with SpatialWeights(:) length = ',TempMaskLength, &
- ',which conflicts with AttrVect_lsize(inAv) = ',length
- call die(myname_)
- endif
- !==========================================================
- ! If the argument iMaskTags is present, create the combined
- ! iMask array:
- !==========================================================
- if(present(iMaskTags)) then ! assemble iMask(:) from all the integer
- ! mask attributes stored in GGrid(:)
- allocate(iMask(length), iMaskTemp(length), stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(3a,i8)') myname_,':: allocate(iMask(...) failed,', &
- ' ierr=',ierr
- call die(myname_)
- endif
- niM = List_nitem(iMaskList)
- do i=1,niM
- ! Retrieve current iMask tag, and get this attribute from GGrid:
- call List_get(DummStr, i, iMaskList)
- call GeneralGrid_exportIAttr(GGrid, String_toChar(DummStr), &
- iMaskTemp, TempMaskLength)
- call String_clean(DummStr)
- if(TempMaskLength /= length) then
- write(stderr,'(3a,i8,a,i8)') myname_,&
- ':: error on return from GeneralGrid_exportIAttr().' , &
- 'Returned with TempMaskLength = ',TempMaskLength, &
- ',which conflicts with AttrVect_lsize(inAv) = ',length
- call die(myname_)
- endif
- if(i == 1) then ! first pass--examine iMaskTemp(:) only
- if(UseFastMethod) then ! straight copy of iMaskTemp(:)
- do j=1,length
- iMask(j) = iMaskTemp(j)
- end do
- else ! go through the entries of iMaskTemp(:) one-by-one
- do j=1,length
- select case(iMaskTemp(j))
- case(0)
- iMask(j) = 0
- case(1)
- iMask(j) = 1
- case default
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: FATAL--illegal INTEGER mask entry. Integer mask ', &
- 'entries must be 0 or 1. iMask(',j,') = ', iMask(j)
- call die(myname_)
- end select ! select case(iMaskTemp(j))...
- end do ! do j=1,length
- endif ! if(UseFastMethod)...
- else ! That is, i /= 1 ...
- if(UseFastMethod) then ! straight product of iMask(:)
- ! and iMaskTemp(:)
- do j=1,length
- iMask(j) = iMask(j) * iMaskTemp(j)
- end do
- else ! go through the entries of iMaskTemp(:) one-by-one
- do j=1,length
- select case(iMaskTemp(j))
- case(0) ! zero out iMask(j)
- iMask(j) = 0
- case(1) ! do nothing
- case default
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: FATAL--illegal INTEGER mask entry. Integer mask ', &
- 'entries must be 0 or 1. iMask(',j,') = ', iMask(j)
- call die(myname_)
- end select ! select case(iMaskTemp(j))...
- end do ! do j=1,length
- endif ! if(UseFastMethod)...
- endif ! if(i == 1)...
- end do ! do i=1,niM...iMask retrievals
- endif ! if(present(iMaskTags))...
- !==========================================================
- ! If the argument rMaskTags is present, create the combined
- ! REAL mask rMask array:
- !==========================================================
- if(present(rMaskTags)) then ! assemble rMask(:) from all the integer
- ! mask attributes stored in GGrid(:)
- allocate(rMask(length), rMaskTemp(length), stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(3a,i8)') myname_,':: allocate(rMask(...) failed,', &
- ' ierr=',ierr
- call die(myname_)
- endif
- nrM = List_nitem(rMaskList)
- do i=1,nrM
- ! Retrieve current rMask tag, and get this attribute from GGrid:
- call List_get(DummStr, i, rMaskList)
- call GeneralGrid_exportRAttr(GGrid, String_toChar(DummStr), &
- rMaskTemp, TempMaskLength)
- call String_clean(DummStr)
- if(TempMaskLength /= length) then
- write(stderr,'(3a,i8,a,i8)') myname_,&
- ':: error on return from GeneralGrid_exportRAttr().' , &
- 'Returned with TempMaskLength = ',TempMaskLength, &
- ',which conflicts with AttrVect_lsize(inAv) = ',length
- call die(myname_)
- endif
- if(i == 1) then ! first pass--examine rMaskTemp(:) only
- if(UseFastMethod) then ! straight copy of rMaskTemp(:)
- do j=1,length
- rMask(j) = rMaskTemp(j)
- end do
- else ! go through the entries of rMaskTemp(:) one-by-one
- ! to ensure they are in the range [0.,1.]
- do j=1,length
- if((rMaskTemp(j) >= 0.) .or. (rMaskTemp(j) <=1.)) then
- rMask(j) = rMaskTemp(j)
- else
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: FATAL--illegal REAL mask entry. Real mask ', &
- 'entries must be in [0.,1.] rMask(',j,') = ', rMask(j)
- call die(myname_)
- endif ! if((rMaskTemp(j) >= 0.) .or. (rMaskTemp(j) <=1.))...
- end do ! do j=1,length
- endif ! if(UseFastMethod)...
- else ! That is, i /= 1 ...
- if(UseFastMethod) then ! straight product of rMask(:)
- ! and rMaskTemp(:)
- do j=1,length
- rMask(j) = rMask(j) * rMaskTemp(j)
- end do
- else ! go through the entries of rMaskTemp(:) one-by-one
- ! to ensure they are in the range [0.,1.]
- do j=1,length
- if((rMaskTemp(j) >= 0.) .or. (rMaskTemp(j) <=1.)) then
- rMask(j) = rMask(j) * rMaskTemp(j)
- else
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: FATAL--illegal REAL mask entry. Real mask ', &
- 'entries must be in [0.,1.] rMask(',j,') = ', rMask(j)
- call die(myname_)
- endif ! if((rMaskTemp(j) >= 0.) .or. (rMaskTemp(j) <=1.))...
- end do ! do j=1,length
- endif ! if(UseFastMethod)...
- endif ! if(i == 1)...
- end do ! do i=1,niM...rMask retrievals
- endif ! if(present(rMaskTags))...
- !==========================================================
- ! Now that we have produced single INTEGER and REAL masks,
- ! compute the masked weighted sum.
- !==========================================================
- if(present(rMaskTags)) then ! We have a REAL Mask
- if(present(iMaskTags)) then ! and an INTEGER Mask
- if(present(comm)) then ! compute distributed AllReduce-style sum:
-
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask, rMask, UseFastMethod, &
- SumWeights, WeightSumTag, comm)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask, rMask, UseFastMethod, &
- comm=comm)
- endif ! if(mySumWeights)...
- else ! compute local sum:
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask, rMask, UseFastMethod, &
- SumWeights, WeightSumTag)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask, rMask, UseFastMethod)
- endif ! if(mySumWeights)...
- endif ! if(present(comm))...
- else ! REAL Mask Only Case...
- if(present(comm)) then ! compute distributed AllReduce-style sum:
-
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- rMask=rMask, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- rMask=rMask, &
- UseFastMethod=UseFastMethod, &
- comm=comm)
- endif ! if(mySumWeights)...
- else ! compute local sum:
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- rMask=rMask, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- rMask=rMask, &
- UseFastMethod=UseFastMethod)
- endif ! if(mySumWeights)...
- endif ! if(present(comm))...
- endif
- else ! no REAL Mask...
- if(present(iMaskTags)) then ! INTEGER Mask Only Case...
- if(present(comm)) then ! compute distributed AllReduce-style sum:
-
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask=iMask, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask=iMask, &
- UseFastMethod=UseFastMethod, &
- comm=comm)
- endif ! if(mySumWeights)...
- else ! compute local sum:
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask=iMask, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- iMask=iMask, &
- UseFastMethod=UseFastMethod)
- endif ! if(mySumWeights)...
- endif ! if(present(comm))...
- else ! no INTEGER Mask / no REAL Mask Case...
- if(present(comm)) then ! compute distributed AllReduce-style sum:
-
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- UseFastMethod=UseFastMethod, &
- comm=comm)
- endif ! if(mySumWeights)...
- else ! compute local sum:
- if(mySumWeights) then ! return the global masked sum of the
- ! weights in outAV
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- UseFastMethod=UseFastMethod, &
- SumWeights=SumWeights, &
- WeightSumTag=WeightSumTag)
- else ! Do not return the masked sum of the weights
- call MaskedSpatialIntegralV(inAv, outAv, SpatialWeights, &
- UseFastMethod=UseFastMethod)
- endif ! if(mySumWeights)...
- endif ! if(present(comm))...
- endif ! if(present(iMaskTags)...
- endif ! if(present(rMaskTags)...
- !==========================================================
- ! The masked spatial integral is now completed.
- ! Clean up the the various allocated mask structures.
- !==========================================================
- if(present(iMaskTags)) then ! clean up iMask and friends...
- call List_clean(iMaskList)
- deallocate(iMask, iMaskTemp, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(3a,i8)') myname_,':: deallocate(iMask(...) failed,', &
- ' ierr=',ierr
- call die(myname_)
- endif
- endif
- if(present(rMaskTags)) then ! clean up rMask and co...
- call List_clean(rMaskList)
- deallocate(rMask, rMaskTemp, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(3a,i8)') myname_,':: deallocate(rMask(...) failed,', &
- ' ierr=',ierr
- call die(myname_)
- endif
- endif
- ! Clean up SpatialWeights(:)
- deallocate(SpatialWeights, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(3a,i8)') myname_,':: deallocate(SpatialWeights(...) failed,', &
- ' ierr=',ierr
- call die(myname_)
- endif
- end subroutine MaskedSpatialIntegralRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: MaskedSpatialAverageRAttrGG_ - Masked spatial average.
- !
- ! !DESCRIPTION:
- ! This routine computes masked spatial averages of the {\tt REAL}
- ! attributes of the input {\tt AttrVect} argument {\tt inAv}, returning
- ! the masked averages in the output {\tt AttrVect} {\tt outAv}. All of
- ! the masking data are assumed stored in the input {\tt GeneralGrid}
- ! argument {\tt GGrid}. If integer masks are to be used, their integer
- ! attribute names in {\tt GGrid} are named as a colon-delimited list
- ! in the optional {\tt CHARACTER} input argument {\tt iMaskTags}. Real
- ! masks (if desired) are referenced by their real attribute names in
- ! {\tt GGrid} are named as a colon-delimited list in the optional
- ! {\tt CHARACTER} input argument {\tt rMaskTags}. The user specifies
- ! a choice of mask combination method with the input {\tt LOGICAL} argument
- ! {\tt UseFastMethod}. If ${\tt UseFastMethod} = {\tt .FALSE.}$ this
- ! routine checks each mask entry to ensure that the integer masks contain
- ! only ones and zeroes, and that entries in the real masks are all in
- ! the closed interval $[0,1]$. If ${\tt UseFastMethod} = {\tt .TRUE.}$,
- ! this routine performs direct products of the masks, assuming that the
- ! user has validated them in advance. This averaging can either be a
- ! local (equivalent to a global memory space operation), or a global
- ! distributed integral. The latter is the case if the optional input
- ! {\tt INTEGER} argument {\tt comm} is supplied (which corresponds to a
- ! Fortran MPI communicatior handle).
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv}
- ! and the input {\tt GeneralGrid} {\tt GGrid} must be equal. That is,
- ! there must be a one-to-one correspondence between the field point values
- ! stored in {\tt inAv} and the point weights stored in {\tt GGrid}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} argument {\tt outAv} is an
- ! allocated data structure. The user must deallocate it using the routine
- ! {\tt AttrVect\_clean()} when it is no longer needed. Failure to do so
- ! will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine MaskedSpatialAverageRAttrGG_(inAv, outAv, GGrid, SpatialWeightTag, &
- iMaskTags, rMaskTags, UseFastMethod, &
- comm)
- ! ! USES:
- use m_realkinds, only : FP
- use m_stdio
- use m_die
- use m_mpif90
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_init => init
- use m_AttrVect, only : AttrVect_zero => zero
- use m_AttrVect, only : AttrVect_clean => clean
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_AttrVect, only : AttrVect_indexRA => indexRA
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_List, only : List
- use m_List, only : List_nullify => nullify
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv
- type(GeneralGrid), intent(IN) :: GGrid
- character(len=*), intent(IN) :: SpatialWeightTag
- character(len=*), optional, intent(IN) :: iMaskTags
- character(len=*), optional, intent(IN) :: rMaskTags
- logical, intent(IN) :: UseFastMethod
- integer, optional, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv
- ! !REVISION HISTORY:
- ! 12Jun02 - J.W. Larson <larson@mcs.anl.gov> - initial version
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::MaskedSpatialAverageRAttrGG_'
- type(AttrVect) :: integratedAv
- type(List) :: nullIList
- character*9, parameter :: WeightSumTag = 'WeightSum'
- integer :: i, iweight
- !================================================================
- ! Do the integration using MaskedSpatialIntegralRAttrGG_(), which
- ! returns the intermediate integrals (including the masked weight
- ! sum) in the AttrVect integratedAv.
- !================================================================
- if(present(iMaskTags)) then
- if(present(rMaskTags)) then ! have both iMasks and rMasks
- if(present(comm)) then ! a distributed parallel sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, iMaskTags, &
- rMaskTags, UseFastMethod, &
- .TRUE., WeightSumTag, comm)
- else ! a purely local sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, iMaskTags, &
- rMaskTags, UseFastMethod, &
- .TRUE., WeightSumTag)
- endif ! if(present(comm))...
- else ! Only iMasks are in use
- if(present(comm)) then ! a distributed parallel sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, iMaskTags, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! a purely local sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, iMaskTags, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag)
- endif ! if(present(comm))...
- endif ! if(present(rMaskTags)...
- else ! no iMasks
- if(present(rMaskTags)) then ! Only rMasks are in use
- if(present(comm)) then ! a distributed parallel sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, &
- rMaskTags=rMaskTags, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! a purely local sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, &
- rMaskTags=rMaskTags, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag)
- endif
- else ! Neither iMasks nor rMasks are in use
- if(present(comm)) then ! a distributed parallel sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag, &
- comm=comm)
- else ! a purely local sum
- call MaskedSpatialIntegralRAttrGG_(inAv, integratedAv, GGrid, &
- SpatialWeightTag, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=WeightSumTag)
- endif ! if(present(comm))...
- endif ! if(present(rMaskTags))...
- endif ! if(present(iMaskTags))...
- !================================================================
- ! The masked integrals and masked weight sum now reside in
- ! in the AttrVect integratedAv. We now wish to compute the
- ! averages by dividing the integtrals by the masked weight sum.
- !================================================================
- ! Check value of summed weights (to avoid division by zero):
- iweight = AttrVect_indexRA(integratedAv, WeightSumTag)
- if(integratedAv%rAttr(iweight, 1) == 0._FP) then
- write(stderr,'(2a)') myname_, &
- '::ERROR--Global sum of grid weights is zero.'
- call die(myname_)
- endif
- ! Initialize output AttrVect outAv:
- call List_nullify(nullIList)
- call AttrVect_init(outAv, iList=nullIList, rList=inAv%rList, lsize=1)
- call AttrVect_zero(outAv)
- ! Divide by global weight sum to compute spatial averages from
- ! spatial integrals.
- do i=1,AttrVect_nRAttr(outAv)
- outAv%rAttr(i,1) = integratedAv%rAttr(i,1) &
- / integratedAv%rAttr(iweight,1)
- end do
- ! Clean up temporary AttrVect:
- call AttrVect_clean(integratedAv)
- end subroutine MaskedSpatialAverageRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: PairedSpatialIntegralRAttrGG_ - Do two spatial integrals at once.
- !
- ! !DESCRIPTION:
- ! This routine computes spatial integrals of the {\tt REAL} attributes
- ! of the {\tt REAL} attributes of the input {\tt AttrVect} arguments
- ! {\tt inAv1} and {\tt inAv2}, returning the integrals in the output
- ! {\tt AttrVect} arguments {\tt outAv1} and {\tt outAv2}, respectively .
- ! The integrals of {\tt inAv1} and {\tt inAv2} are computed using
- ! spatial weights stored in the input {\tt GeneralGrid} arguments
- ! {\tt GGrid1} and {\tt GGrid2}, respectively. The spatial weights in
- ! in {\tt GGrid1} and {\tt GGrid2} are identified by the input {\tt CHARACTER}
- ! arguments {\tt WeightTag1} and {\tt WeightTag2}, respectively.
- ! If {\tt SpatialIntegralRAttrGG\_()} is invoked with the optional
- ! {\tt LOGICAL} input argument
- ! {\tt SumWeights} set as {\tt .TRUE.}, then the weights are also summed
- ! and stored in {\tt outAv1} and {\tt outAv2}, and can be referenced with
- ! the attribute tags defined by the arguments {\tt WeightTag1} and
- ! {\tt WeightTag2}, respectively. This paired integral is implicitly a
- ! distributed operation (the whole motivation for pairing the integrals is
- ! to reduce communication latency costs), and the Fortran MPI communicator
- ! handle is defined by the input {\tt INTEGER} argument {\tt comm}. The
- ! summation is an AllReduce operation, with all processes receiving the
- ! global sum.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv1}
- ! and the {\tt GeneralGrid} {\tt GGrid1} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv1} and the point weights stored in {\tt GGrid1}. The same
- ! relationship must apply between {\tt inAv2} and {\tt GGrid2}.
- !
- ! {\bf N.B.: } If {\tt SpatialIntegralRAttrGG\_()} is invoked with the
- ! optional {\tt LOGICAL} input argument {\tt SumWeights} set as {\tt .TRUE.},
- ! then the value of {\tt WeightTag1} must not conflict with any of the
- ! {\tt REAL} attribute tags in {\tt inAv1} and the value of {\tt WeightTag2}
- ! must not conflict with any of the {\tt REAL} attribute tags in {\tt inAv2}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} arguments {\tt outAv1} and
- ! {\tt outAv2} are allocated data structures. The user must deallocate them
- ! using the routine {\tt AttrVect\_clean()} when they are no longer needed.
- ! Failure to do so will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine PairedSpatialIntegralRAttrGG_(inAv1, outAv1, GGrid1, WeightTag1, &
- inAv2, outAv2, GGrid2, WeightTag2, &
- SumWeights, comm)
- ! ! USES:
- use m_stdio
- use m_die
- use m_mpif90
- use m_realkinds, only : FP
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_AttrVectReduce, only : AttrVect_LocalWeightedSumRAttr => &
- LocalWeightedSumRAttr
- use m_SpatialIntegralV, only : PairedSpatialIntegralsV
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv1
- type(GeneralGrid), intent(IN) :: GGrid1
- character(len=*), intent(IN) :: WeightTag1
- type(AttrVect), intent(IN) :: inAv2
- type(GeneralGrid), intent(IN) :: GGrid2
- character(len=*), intent(IN) :: WeightTag2
- logical, optional, intent(IN) :: SumWeights
- integer, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv1
- type(AttrVect), intent(OUT) :: outAv2
- ! !REVISION HISTORY:
- ! 09May02 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
- ! 10Jun02 - J.W. Larson <larson@mcs.anl.gov> - Refactored--now
- ! built on top of PairedIntegralRAttrV_().
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::PairedSpatialIntegralRAttrGG_'
- ! Argument Sanity Checks:
- integer :: ierr, length1, length2
- logical :: mySumWeights
- real(FP), dimension(:), pointer :: gridWeights1, gridWeights2
- ! Argument Validity Checks
- if(AttrVect_lsize(inAv1) /= GeneralGrid_lsize(GGrid1)) then
- ierr = AttrVect_lsize(inAv1) - GeneralGrid_lsize(GGrid1)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv1 / GGrid1 length mismatch: ', &
- ' AttrVect_lsize(inAv1) = ',AttrVect_lsize(inAv1), &
- ' GeneralGrid_lsize(GGrid1) = ',GeneralGrid_lsize(GGrid1)
- call die(myname_)
- endif
- if(AttrVect_lsize(inAv2) /= GeneralGrid_lsize(GGrid2)) then
- ierr = AttrVect_lsize(inAv2) - GeneralGrid_lsize(GGrid2)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv2 / GGrid2 length mismatch: ', &
- ' AttrVect_lsize(inAv2) = ',AttrVect_lsize(inAv2), &
- ' GeneralGrid_lsize(GGrid2) = ',GeneralGrid_lsize(GGrid2)
- call die(myname_)
- endif
- ! Are we summing the integration weights for either input
- ! GeneralGrid?
- if(present(SumWeights)) then
- mySumWeights = SumWeights
- else
- mySumWeights = .FALSE.
- endif
- ! ensure unambiguous pointer association status for gridWeights1
- ! and gridWeights2
- nullify(gridWeights1)
- nullify(gridWeights2)
- ! Extract Grid Weights
- call GeneralGrid_exportRAttr(GGrid1, WeightTag1, gridWeights1, length1)
- call GeneralGrid_exportRAttr(GGrid2, WeightTag2, gridWeights2, length2)
- call PairedSpatialIntegralsV(inAv1, outAv1, gridweights1, WeightTag1, &
- inAv2, outAv2, gridweights2, WeightTag2, &
- mySumWeights, comm)
- ! Clean up allocated arrays:
- deallocate(gridWeights1, gridWeights2, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- 'ERROR--deallocate(gridWeights1,...) failed, ierr = ',ierr
- call die(myname_)
- endif
- end subroutine PairedSpatialIntegralRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: PairedSpatialAverageRAttrGG_ - Do two spatial averages at once.
- !
- ! !DESCRIPTION:
- ! This routine computes spatial averages of the {\tt REAL} attributes
- ! of the {\tt REAL} attributes of the input {\tt AttrVect} arguments
- ! {\tt inAv1} and {\tt inAv2}, returning the integrals in the output
- ! {\tt AttrVect} arguments {\tt outAv1} and {\tt outAv2}, respectively .
- ! The integrals of {\tt inAv1} and {\tt inAv2} are computed using
- ! spatial weights stored in the input {\tt GeneralGrid} arguments
- ! {\tt GGrid1} and {\tt GGrid2}, respectively. The spatial weights in
- ! in {\tt GGrid1} and {\tt GGrid2} are identified by the input {\tt CHARACTER}
- ! arguments {\tt WeightTag1} and {\tt WeightTag2}, respectively.
- ! This paired average is implicitly a
- ! distributed operation (the whole motivation for pairing the averages is
- ! to reduce communication latency costs), and the Fortran MPI communicator
- ! handle is defined by the input {\tt INTEGER} argument {\tt comm}. The
- ! summation is an AllReduce operation, with all processes receiving the
- ! global sum.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv1}
- ! and the {\tt GeneralGrid} {\tt GGrid1} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv1} and the point weights stored in {\tt GGrid1}. The same
- ! relationship must apply between {\tt inAv2} and {\tt GGrid2}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} arguments {\tt outAv1} and
- ! {\tt outAv2} are allocated data structures. The user must deallocate them
- ! using the routine {\tt AttrVect\_clean()} when they are no longer needed.
- ! Failure to do so will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine PairedSpatialAverageRAttrGG_(inAv1, outAv1, GGrid1, WeightTag1, &
- inAv2, outAv2, GGrid2, WeightTag2, &
- comm)
- ! ! USES:
- use m_realkinds, only : FP
-
- use m_stdio
- use m_die
- use m_mpif90
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_init => init
- use m_AttrVect, only : AttrVect_zero => zero
- use m_AttrVect, only : AttrVect_clean => clean
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_AttrVect, only : AttrVect_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_AttrVectReduce, only : AttrVect_LocalWeightedSumRAttr => &
- LocalWeightedSumRAttr
- use m_List, only : List
- use m_List, only : List_nullify => nullify
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv1
- type(GeneralGrid), intent(IN) :: GGrid1
- character(len=*), intent(IN) :: WeightTag1
- type(AttrVect), intent(IN) :: inAv2
- type(GeneralGrid), intent(IN) :: GGrid2
- character(len=*), intent(IN) :: WeightTag2
- integer, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv1
- type(AttrVect), intent(OUT) :: outAv2
- ! !REVISION HISTORY:
- ! 09May02 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
- ! 14Jun02 - J.W. Larson <larson@mcs.anl.gov> - Bug fix to reflect
- ! new interface to PairedSpatialIntegralRAttrGG_().
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_=myname//'::PairedSpatialAverageRAttrGG_'
- type(AttrVect) :: integratedAv1, integratedAv2
- type(List) :: nullIList
- integer :: i, ierr, iweight1, iweight2
- ! Compute the spatial integral:
- call PairedSpatialIntegralRAttrGG_(inAv1, integratedAv1, GGrid1, WeightTag1, &
- inAv2, integratedAv2, GGrid2, &
- WeightTag2, .TRUE., comm)
- ! Check value of summed weights (to avoid division by zero):
- iweight1 = AttrVect_indexRA(integratedAv1, WeightTag1)
- if(integratedAv1%rAttr(iweight1, 1) == 0._FP) then
- write(stderr,'(2a)') myname_, &
- '::ERROR--Global sum of grid weights in first integral is zero.'
- call die(myname_)
- endif
- iweight2 = AttrVect_indexRA(integratedAv2, WeightTag2)
- if(integratedAv2%rAttr(iweight2, 1) == 0._FP) then
- write(stderr,'(2a)') myname_, &
- '::ERROR--Global sum of grid weights in second integral is zero.'
- call die(myname_)
- endif
- ! Initialize output AttrVects outAv1 and outAv2:
- call List_nullify(nullIList)
- call AttrVect_init(outAv1, iList=nullIList, rList=inAv1%rList, lsize=1)
- call AttrVect_zero(outAv1)
- call AttrVect_init(outAv2, iList=nullIList, rList=InAv2%rList, lsize=1)
- call AttrVect_zero(outAv2)
- ! Divide by global weight sum to compute spatial averages from
- ! spatial integrals.
- do i=1,AttrVect_nRAttr(outAv1)
- outAv1%rAttr(i,1) = integratedAv1%rAttr(i,1) &
- / integratedAv1%rAttr(iweight1,1)
- end do
- do i=1,AttrVect_nRAttr(outAv2)
- outAv2%rAttr(i,1) = integratedAv2%rAttr(i,1) &
- / integratedAv2%rAttr(iweight2,1)
- end do
- ! Clean up temporary AttrVects:
- call AttrVect_clean(integratedAv1)
- call AttrVect_clean(integratedAv2)
- end subroutine PairedSpatialAverageRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: PairedMaskedIntegralRAttrGG_ - Do two masked integrals at once.
- !
- ! !DESCRIPTION:
- ! This routine computes a pair of masked spatial integrals of the {\tt REAL}
- ! attributes of the input {\tt AttrVect} arguments {\tt inAv} and
- ! {\tt inAv2}, returning the masked integrals in the output {\tt AttrVect}
- ! {\tt outAv1} and {\tt outAv2}, respectively. All of the spatial weighting
- ! and masking data for each set of integrals are assumed stored in the input
- ! {\tt GeneralGrid} arguments {\tt GGrid} and {\tt GGrid2}. If integer
- ! masks are to be used, their integer attribute names in {\tt GGrid1}
- ! and {\tt GGrid2} are named as a colon-delimited lists in the optional
- ! {\tt CHARACTER} input arguments {\tt iMaskTags1} and {\tt iMaskTags2},
- ! respectively. Real masks (if desired) are referenced by their real
- ! attribute names in {\tt GGrid1} and {\tt GGrid2} are named as
- ! colon-delimited lists in the optional {\tt CHARACTER} input arguments
- ! {\tt rMaskTags1} and {\tt rMaskTags2}, respectively. The user specifies
- ! a choice of mask combination method with the input {\tt LOGICAL} argument
- ! {\tt UseFastMethod}. If ${\tt UseFastMethod} = {\tt .FALSE.}$ this
- ! routine checks each mask entry to ensure that the integer masks contain
- ! only ones and zeroes, and that entries in the real masks are all in
- ! the closed interval $[0,1]$. If ${\tt UseFastMethod} = {\tt .TRUE.}$,
- ! this routine performs direct products of the masks, assuming that the
- ! user has validated them in advance. The optional {\tt LOGICAL} input
- ! argument {\tt SumWeights} determines whether the masked sum of the spatial
- ! weights is computed and returned in {\tt outAv1} and {\tt outAv2} with the
- ! real attribute names supplied in the {\tt CHARACTER} input arguments
- ! {\tt SpatialWeightTag1}, and {\tt SpatialWeightTag2}, respectively.
- ! This paired integral is implicitly a distributed operation (the whole
- ! motivation for pairing the averages is to reduce communication latency
- ! costs), and the Fortran MPI communicator handle is defined by the input
- ! {\tt INTEGER} argument {\tt comm}. The
- ! summation is an AllReduce operation, with all processes receiving the
- ! global sum.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv1}
- ! and the {\tt GeneralGrid} {\tt GGrid1} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv1} and the point weights stored in {\tt GGrid1}. The same
- ! relationship must apply between {\tt inAv2} and {\tt GGrid2}.
- !
- ! {\bf N.B.: } If {\tt PairedMaskedIntegralRAttrGG\_()} is invoked with the
- ! optional {\tt LOGICAL} input argument {\tt SumWeights} set as {\tt .TRUE.},
- ! then the value of {\tt SpatialWeightTag1} must not conflict with any of the
- ! {\tt REAL} attribute tags in {\tt inAv1} and the value of
- ! {\tt SpatialWeightTag2} must not conflict with any of the {\tt REAL}
- ! attribute tags in {\tt inAv2}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} arguments {\tt outAv1} and
- ! {\tt outAv2} are allocated data structures. The user must deallocate them
- ! using the routine {\tt AttrVect\_clean()} when they are no longer needed.
- ! Failure to do so will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine PairedMaskedIntegralRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag1, rMaskTags1, &
- iMaskTags1, inAv2, outAv2, GGrid2, &
- SpatialWeightTag2, rMaskTags2, &
- iMaskTags2, UseFastMethod, &
- SumWeights, comm)
- ! ! USES:
- use m_stdio
- use m_die
- use m_mpif90
- use m_realkinds, only : FP
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_AttrVectReduce, only : AttrVect_LocalWeightedSumRAttr => &
- LocalWeightedSumRAttr
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv1
- type(GeneralGrid), intent(IN) :: GGrid1
- character(len=*), intent(IN) :: SpatialWeightTag1
- character(len=*), optional, intent(IN) :: iMaskTags1
- character(len=*), optional, intent(IN) :: rMaskTags1
- type(AttrVect), intent(IN) :: inAv2
- type(GeneralGrid), intent(IN) :: GGrid2
- character(len=*), intent(IN) :: SpatialWeightTag2
- character(len=*), optional, intent(IN) :: iMaskTags2
- character(len=*), optional, intent(IN) :: rMaskTags2
- logical, intent(IN) :: UseFastMethod
- logical, optional, intent(IN) :: SumWeights
- integer, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv1
- type(AttrVect), intent(OUT) :: outAv2
- ! !REVISION HISTORY:
- ! 17Jun02 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
- ! 19Jun02 - J.W. Larson <larson@mcs.anl.gov> - Shortened the name
- ! for compatibility with the Portland Group f90 compiler
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_ = &
- myname//'::PairedMaskedIntegralRAttrGG_'
- logical :: mySumWeights
- real(FP), dimension(:), pointer :: PairedBuffer, OutPairedBuffer
- integer :: ierr, nRA1, nRA2, PairedBufferLength
- ! Basic Argument Validity Checks:
- if(AttrVect_lsize(inAv1) /= GeneralGrid_lsize(GGrid1)) then
- ierr = AttrVect_lsize(inAv1) - GeneralGrid_lsize(GGrid1)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv1 / GGrid1 length mismatch: ', &
- ' AttrVect_lsize(inAv1) = ',AttrVect_lsize(inAv1), &
- ' GeneralGrid_lsize(GGrid1) = ',GeneralGrid_lsize(GGrid1)
- call die(myname_)
- endif
- if(AttrVect_lsize(inAv2) /= GeneralGrid_lsize(GGrid2)) then
- ierr = AttrVect_lsize(inAv2) - GeneralGrid_lsize(GGrid2)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv2 / GGrid2 length mismatch: ', &
- ' AttrVect_lsize(inAv2) = ',AttrVect_lsize(inAv2), &
- ' GeneralGrid_lsize(GGrid2) = ',GeneralGrid_lsize(GGrid2)
- call die(myname_)
- endif
- ! Are we summing the integration weights for the input
- ! GeneralGrids?
- if(present(SumWeights)) then
- mySumWeights = SumWeights
- else
- mySumWeights = .FALSE.
- endif
- ! Begin by invoking MaskedSpatialIntegralRAttrGG_() for each
- ! AttrVect/GeneralGrid pair. This is done LOCALLY to create
- ! integratedAv1 and integratedAv2, respectively.
- ! Local Masked Integral #1:
- if(present(iMaskTags1)) then
- if(present(rMaskTags1)) then ! both Integer and Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag1, iMaskTags1, &
- rMaskTags1, UseFastMethod, &
- mySumWeights, SpatialWeightTag1)
- else ! Integer Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag1, &
- iMaskTags=iMaskTags1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag1)
- endif ! if(present(rMaskTags1))...
- else ! No Integer Masking
- if(present(rMaskTags1)) then ! Real Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag=SpatialWeightTag1, &
- rMaskTags=rMaskTags1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag1)
- else ! Neither Integer nor Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag=SpatialWeightTag1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag1)
- endif ! if(present(rMaskTags1))...
- endif ! if(present(iMaskTags1))...
- ! Local Masked Integral #2:
- if(present(iMaskTags2)) then
- if(present(rMaskTags2)) then ! both Integer and Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv2, outAv2, GGrid2, &
- SpatialWeightTag2, iMaskTags2, &
- rMaskTags2, UseFastMethod, &
- mySumWeights, SpatialWeightTag2)
- else ! Integer Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv2, outAv2, GGrid2, &
- SpatialWeightTag2, &
- iMaskTags=iMaskTags2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag2)
- endif ! if(present(rMaskTags2))...
- else ! No Integer Masking
- if(present(rMaskTags2)) then ! Real Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv2, outAv2, GGrid2, &
- SpatialWeightTag=SpatialWeightTag2, &
- rMaskTags=rMaskTags2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag2)
- else ! Neither Integer nor Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv2, outAv2, GGrid2, &
- SpatialWeightTag=SpatialWeightTag2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=mySumWeights, &
- WeightSumTag=SpatialWeightTag2)
- endif ! if(present(rMaskTags2))...
- endif ! if(present(iMaskTags2))...
- ! Create the paired buffer for the Global Sum
- nRA1 = AttrVect_nRAttr(outAv1)
- nRA2 = AttrVect_nRAttr(outAv2)
- PairedBufferLength = nRA1 + nRA2
- allocate(PairedBuffer(PairedBufferLength), OutPairedBuffer(PairedBufferLength), &
- stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal error--allocate(PairedBuffer...failed, ierr = ',ierr
- call die(myname_)
- endif
- ! Load the paired buffer
- PairedBuffer(1:nRA1) = outAv1%rAttr(1:nRA1,1)
- PairedBuffer(nRA1+1:PairedBufferLength) = outAv2%rAttr(1:nRA2,1)
- ! Perform the global sum on the paired buffer
- call MPI_AllReduce(PairedBuffer, OutPairedBuffer, PairedBufferLength, &
- MP_Type(PairedBuffer(1)), MP_SUM, comm, ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal Error--MPI_ALLREDUCE() failed with ierror = ',ierr
- call MP_perr_die(myname_,'MPI_ALLREDUCE() failed',ierr)
- endif
- ! Unload OutPairedBuffer into outAv1 and outAv2:
- outAv1%rAttr(1:nRA1,1) = OutPairedBuffer(1:nRA1)
- outAv2%rAttr(1:nRA2,1) = OutPairedBuffer(nRA1+1:PairedBufferLength)
- deallocate(PairedBuffer, OutPairedBuffer, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal error--deallocate(PairedBuffer...failed, ierr = ',ierr
- call die(myname_)
- endif
- end subroutine PairedMaskedIntegralRAttrGG_
- !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! Math and Computer Science Division, Argonne National Laboratory !
- !BOP -------------------------------------------------------------------
- !
- ! !IROUTINE: PairedMaskedAverageRAttrGG_ - Do two masked averages at once.
- !
- ! !DESCRIPTION:
- ! This routine computes a pair of masked spatial averages of the {\tt REAL}
- ! attributes of the input {\tt AttrVect} arguments {\tt inAv} and
- ! {\tt inAv2}, returning the masked averagess in the output {\tt AttrVect}
- ! {\tt outAv1} and {\tt outAv2}, respectively. All of the spatial weighting
- ! and masking data for each set of averages are assumed stored in the input
- ! {\tt GeneralGrid} arguments {\tt GGrid} and {\tt GGrid2}. If integer
- ! masks are to be used, their integer attribute names in {\tt GGrid1}
- ! and {\tt GGrid2} are named as a colon-delimited lists in the optional
- ! {\tt CHARACTER} input arguments {\tt iMaskTags1} and {\tt iMaskTags2},
- ! respectively. Real masks (if desired) are referenced by their real
- ! attribute names in {\tt GGrid1} and {\tt GGrid2} are named as
- ! colon-delimited lists in the optional {\tt CHARACTER} input arguments
- ! {\tt rMaskTags1} and {\tt rMaskTags2}, respectively. The user specifies
- ! a choice of mask combination method with the input {\tt LOGICAL} argument
- ! {\tt UseFastMethod}. If ${\tt UseFastMethod} = {\tt .FALSE.}$ this
- ! routine checks each mask entry to ensure that the integer masks contain
- ! only ones and zeroes, and that entries in the real masks are all in
- ! the closed interval $[0,1]$. If ${\tt UseFastMethod} = {\tt .TRUE.}$,
- ! this routine performs direct products of the masks, assuming that the
- ! user has validated them in advance. This paired average is implicitly
- ! a distributed operation (the whole motivation for pairing the averages
- ! is to reduce communication latency costs), and the Fortran MPI communicator
- ! handle is defined by the input {\tt INTEGER} argument {\tt comm}. The
- ! summation is an AllReduce operation, with all processes receiving the
- ! global sum.
- !
- ! {\bf N.B.: } The local lengths of the {\tt AttrVect} argument {\tt inAv1}
- ! and the {\tt GeneralGrid} {\tt GGrid1} must be equal. That is, there
- ! must be a one-to-one correspondence between the field point values stored
- ! in {\tt inAv1} and the point weights stored in {\tt GGrid1}. The same
- ! relationship must apply between {\tt inAv2} and {\tt GGrid2}.
- !
- ! {\bf N.B.: } The output {\tt AttrVect} arguments {\tt outAv1} and
- ! {\tt outAv2} are allocated data structures. The user must deallocate them
- ! using the routine {\tt AttrVect\_clean()} when they are no longer needed.
- ! Failure to do so will result in a memory leak.
- !
- ! !INTERFACE:
- subroutine PairedMaskedAverageRAttrGG_(inAv1, outAv1, GGrid1, &
- SpatialWeightTag1, rMaskTags1, &
- iMaskTags1, inAv2, outAv2, GGrid2, &
- SpatialWeightTag2, rMaskTags2, &
- iMaskTags2, UseFastMethod, &
- comm)
- ! ! USES:
- use m_stdio
- use m_die
- use m_mpif90
- use m_realkinds, only : FP
- use m_AttrVect, only : AttrVect
- use m_AttrVect, only : AttrVect_init => init
- use m_AttrVect, only : AttrVect_zero => zero
- use m_AttrVect, only : AttrVect_clean => clean
- use m_AttrVect, only : AttrVect_lsize => lsize
- use m_AttrVect, only : AttrVect_nRAttr => nRAttr
- use m_GeneralGrid, only : GeneralGrid
- use m_GeneralGrid, only : GeneralGrid_lsize => lsize
- use m_GeneralGrid, only : GeneralGrid_indexRA => indexRA
- use m_GeneralGrid, only : GeneralGrid_exportRAttr => exportRAttr
- use m_AttrVectReduce, only : AttrVect_LocalWeightedSumRAttr => &
- LocalWeightedSumRAttr
- use m_List, only : List
- use m_List, only : List_nullify => nullify
- implicit none
- ! !INPUT PARAMETERS:
- type(AttrVect), intent(IN) :: inAv1
- type(GeneralGrid), intent(IN) :: GGrid1
- character(len=*), intent(IN) :: SpatialWeightTag1
- character(len=*), optional, intent(IN) :: iMaskTags1
- character(len=*), optional, intent(IN) :: rMaskTags1
- type(AttrVect), intent(IN) :: inAv2
- type(GeneralGrid), intent(IN) :: GGrid2
- character(len=*), intent(IN) :: SpatialWeightTag2
- character(len=*), optional, intent(IN) :: iMaskTags2
- character(len=*), optional, intent(IN) :: rMaskTags2
- logical, intent(IN) :: UseFastMethod
- integer, intent(IN) :: comm
- ! !OUTPUT PARAMETERS:
- type(AttrVect), intent(OUT) :: outAv1
- type(AttrVect), intent(OUT) :: outAv2
- ! !REVISION HISTORY:
- ! 17Jun02 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
- ! 19Jun02 - J.W. Larson <larson@mcs.anl.gov> - Shortened the name
- ! for compatibility with the Portland Group f90 compiler
- ! 25Jul02 - J.W. Larson E.T. Ong - Bug fix. This routine was
- ! previously doing integrals rather than area averages.
- !
- !EOP ___________________________________________________________________
- character(len=*),parameter :: myname_ = &
- myname//'::PairedMaskedAverageRAttrGG_'
- type(AttrVect) :: LocalIntegral1, LocalIntegral2
- type(List) :: nullIList
- real(FP), dimension(:), pointer :: PairedBuffer, OutPairedBuffer
- integer :: i, ierr, nRA1, nRA2, PairedBufferLength
- real(FP) :: WeightSumInv
- ! Basic Argument Validity Checks:
- if(AttrVect_lsize(inAv1) /= GeneralGrid_lsize(GGrid1)) then
- ierr = AttrVect_lsize(inAv1) - GeneralGrid_lsize(GGrid1)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv1 / GGrid1 length mismatch: ', &
- ' AttrVect_lsize(inAv1) = ',AttrVect_lsize(inAv1), &
- ' GeneralGrid_lsize(GGrid1) = ',GeneralGrid_lsize(GGrid1)
- call die(myname_)
- endif
- if(AttrVect_lsize(inAv2) /= GeneralGrid_lsize(GGrid2)) then
- ierr = AttrVect_lsize(inAv2) - GeneralGrid_lsize(GGrid2)
- write(stderr,'(3a,i8,a,i8)') myname_, &
- ':: inAv2 / GGrid2 length mismatch: ', &
- ' AttrVect_lsize(inAv2) = ',AttrVect_lsize(inAv2), &
- ' GeneralGrid_lsize(GGrid2) = ',GeneralGrid_lsize(GGrid2)
- call die(myname_)
- endif
- ! Begin by invoking MaskedSpatialIntegralRAttrGG_() for each
- ! AttrVect/GeneralGrid pair. This is done LOCALLY to create
- ! LocalIntegral1 and LocalIntegral2, respectively.
- ! Local Masked Integral #1:
- if(present(iMaskTags1)) then
- if(present(rMaskTags1)) then ! both Integer and Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv1, LocalIntegral1, GGrid1, &
- SpatialWeightTag1, iMaskTags1, &
- rMaskTags1, UseFastMethod, &
- .TRUE., SpatialWeightTag1)
- else ! Integer Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv1, LocalIntegral1, GGrid1, &
- SpatialWeightTag1, &
- iMaskTags=iMaskTags1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag1)
- endif ! if(present(rMaskTags1))...
- else ! No Integer Masking
- if(present(rMaskTags1)) then ! Real Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv1, LocalIntegral1, GGrid1, &
- SpatialWeightTag=SpatialWeightTag1, &
- rMaskTags=rMaskTags1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag1)
- else ! Neither Integer nor Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv1, LocalIntegral1, GGrid1, &
- SpatialWeightTag=SpatialWeightTag1, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag1)
- endif ! if(present(rMaskTags1))...
- endif ! if(present(iMaskTags1))...
- ! Local Masked Integral #2:
- if(present(iMaskTags2)) then
- if(present(rMaskTags2)) then ! both Integer and Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv2, LocalIntegral2, GGrid2, &
- SpatialWeightTag2, iMaskTags2, &
- rMaskTags2, UseFastMethod, &
- .TRUE., SpatialWeightTag2)
- else ! Integer Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv2, LocalIntegral2, GGrid2, &
- SpatialWeightTag2, &
- iMaskTags=iMaskTags2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag2)
- endif ! if(present(rMaskTags2))...
- else ! No Integer Masking
- if(present(rMaskTags2)) then ! Real Masking Only
- call MaskedSpatialIntegralRAttrGG_(inAv2, LocalIntegral2, GGrid2, &
- SpatialWeightTag=SpatialWeightTag2, &
- rMaskTags=rMaskTags2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag2)
- else ! Neither Integer nor Real Masking
- call MaskedSpatialIntegralRAttrGG_(inAv2, LocalIntegral2, GGrid2, &
- SpatialWeightTag=SpatialWeightTag2, &
- UseFastMethod=UseFastMethod, &
- SumWeights=.TRUE., &
- WeightSumTag=SpatialWeightTag2)
- endif ! if(present(rMaskTags2))...
- endif ! if(present(iMaskTags2))...
- ! Create the paired buffer for the Global Sum
- nRA1 = AttrVect_nRAttr(LocalIntegral1)
- nRA2 = AttrVect_nRAttr(LocalIntegral2)
- PairedBufferLength = nRA1 + nRA2
- allocate(PairedBuffer(PairedBufferLength), OutPairedBuffer(PairedBufferLength), &
- stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal error--allocate(PairedBuffer...failed, ierr = ',ierr
- call die(myname_)
- endif
- ! Load the paired buffer
- PairedBuffer(1:nRA1) = LocalIntegral1%rAttr(1:nRA1,1)
- PairedBuffer(nRA1+1:PairedBufferLength) = LocalIntegral2%rAttr(1:nRA2,1)
- ! Perform the global sum on the paired buffer
- call MPI_AllReduce(PairedBuffer, OutPairedBuffer, PairedBufferLength, &
- MP_Type(PairedBuffer(1)), MP_SUM, comm, ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal Error--MPI_ALLREDUCE() failed with ierror = ',ierr
- call MP_perr_die(myname_,'MPI_ALLREDUCE() failed',ierr)
- endif
- ! Create outAv1 and outAv2 from inAv1 and inAv2, respectively:
- call List_nullify(nullIList)
- call AttrVect_init(outAv1, iList=nullIList, rList=inAv1%rList, lsize=1)
- call AttrVect_zero(outAv1)
- call AttrVect_init(outAv2, iList=nullIList, rList=inAv2%rList, lsize=1)
- call AttrVect_zero(outAv2)
- ! Unload/rescale OutPairedBuffer into outAv1 and outAv2:
- nRA1 = AttrVect_nRAttr(outAv1)
- nRA2 = AttrVect_nRAttr(outAv2)
- ! First outAv1:
- if(OutPairedBuffer(nRA1+1) /= 0.) then
- WeightSumInv = 1._FP / OutPairedBuffer(nRA1+1) ! Sum of weights on grid1
- ! is the nRA1+1th element in
- ! the paired buffer.
- else
- write(stderr,'(2a)') myname_, &
- ':: FATAL ERROR--Sum of the Weights for integral #1 is zero! Terminating...'
- call die(myname_)
- endif
- ! Rescale global integral to get global average:
- do i=1,nRA1
- outAv1%rAttr(i,1) = WeightSumInv * OutPairedBuffer(i)
- end do
- ! And then outAv2:
- if(OutPairedBuffer(PairedBufferLength) /= 0.) then
- WeightSumInv = 1._FP / OutPairedBuffer(PairedBufferLength) ! Sum of weights on grid2
- ! is the last element in
- ! the paired buffer.
- else
- write(stderr,'(2a)') myname_, &
- ':: FATAL ERROR--Sum of the Weights for integral #2 is zero! Terminating...'
- call die(myname_)
- endif
- ! Rescale global integral to get global average:
- do i=1,nRA2
- outAv2%rAttr(i,1) = WeightSumInv * OutPairedBuffer(i+nRA1+1)
- end do
- ! Clean up allocated structures
- call AttrVect_clean(LocalIntegral1)
- call AttrVect_clean(LocalIntegral2)
- deallocate(PairedBuffer, OutPairedBuffer, stat=ierr)
- if(ierr /= 0) then
- write(stderr,'(2a,i8)') myname_, &
- ':: Fatal error--deallocate(PairedBuffer...failed, ierr = ',ierr
- call die(myname_)
- endif
- end subroutine PairedMaskedAverageRAttrGG_
- end module m_SpatialIntegral
|