def updateCoeffs(self):
        try:
            if self.updated():
                return

            from Foam.meshTools import directMappedPatchBase
            mpp = directMappedPatchBase.ext_refCast(self.patch().patch())

            nbrMesh = mpp.sampleMesh()

            from Foam.finiteVolume import fvMesh
            nbrPatch = fvMesh.ext_refCast(nbrMesh).boundary()[
                mpp.samplePolyPatch().index()]

            # Force recalculation of mapping and schedule
            distMap = mpp.map()

            intFld = self.patchInternalField()

            from Foam.finiteVolume import volScalarField
            nbrField = solidWallMixedTemperatureCoupledFvPatchScalarField.ext_refCast(
                volScalarField.ext_lookupPatchField(nbrPatch,
                                                    self.neighbourFieldName_))

            #Swap to obtain full local values of neighbour internal field
            nbrIntFld = nbrField.patchInternalField()

            from Foam.OpenFOAM import mapDistribute, Pstream
            mapDistribute.distribute(
                Pstream.defaultCommsType.fget(),
                distMap.schedule(),
                distMap.constructSize(),
                distMap.subMap(),  #what to send
                distMap.constructMap(),  #what to receive
                nbrIntFld())

            # Swap to obtain full local values of neighbour K*delta
            nbrKDelta = nbrField.K() * nbrPatch.deltaCoeffs()
            mapDistribute.distribute(
                Pstream.defaultCommsType.fget(),
                distMap.schedule(),
                distMap.constructSize(),
                distMap.subMap(),  #what to send
                distMap.constructMap(),  #what to receive
                nbrKDelta())

            myKDelta = self.K() * self.patch().deltaCoeffs()

            # Both sides agree on
            # - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
            # - gradient    : (temperature-fld)*delta
            # We've got a degree of freedom in how to implement this in a mixed bc.
            # (what gradient, what fixedValue and mixing coefficient)
            # Two reasonable choices:
            # 1. specify above temperature on one side (preferentially the high side)
            #    and above gradient on the other. So this will switch between pure
            #    fixedvalue and pure fixedgradient
            # 2. specify gradient and temperature such that the equations are the
            #    same on both sides. This leads to the choice of
            #    - refGradient = zero gradient
            #    - refValue = neighbour value
            #    - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())

            self.refValue().ext_assign(nbrIntFld)
            self.refGrad().ext_assign(0.0)
            self.valueFraction().ext_assign(nbrKDelta /
                                            (nbrKDelta + myKDelta()))

            mixedFvPatchScalarField.updateCoeffs(self)

            if self.debug:
                Q = (self.K() * self.patch().magSf() * self.snGrad()).gSum()


                ext_Info ()<< patch().boundaryMesh().mesh().name()  << ":" \
                           << patch().name() << ':' << self.dimensionedInternalField().name() << " <- " \
                           << nbrMesh.name() << ':' << nbrPatch.name() << ':' << self.dimensionedInternalField().name() << " :" \
                           << " heat[W]:"  << Q << " walltemperature "\
                           << " min:" << self.gMin() << " max:" << self.gMax() << " avg:" << self.gAverage() << nl
                pass
            pass
        except Exception, exc:
            import sys, traceback
            traceback.print_exc(file=sys.stdout)
            raise exc
    def updateCoeffs( self ) :
        try:
            if self.updated() :
                return
            
            from Foam.meshTools import directMappedPatchBase
            mpp = directMappedPatchBase.ext_refCast( self.patch().patch() )
            
            nbrMesh = mpp.sampleMesh()
            intFld = self.patchInternalField()
            
            if self.interfaceOwner( nbrMesh ):
               # Note: other side information could be cached - it only needs
               # to be updated the first time round the iteration (i.e. when
               # switching regions) but unfortunately we don't have this information.
               distMap = mpp.map()
               from Foam.finiteVolume import fvMesh
               nbrPatch = fvMesh.ext_refCast( nbrMesh ).boundary()[ mpp.samplePolyPatch().index() ]
               
               # Calculate the temperature by harmonic averaging
               # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               from Foam.finiteVolume import volScalarField
               nbrField = solidWallMixedTemperatureCoupledFvPatchScalarField.ext_refCast( volScalarField.ext_lookupPatchField( nbrPatch, self.neighbourFieldName_ ) )
               
               #Swap to obtain full local values of neighbour internal field
               nbrIntFld = nbrField.patchInternalField()
               
               from Foam.OpenFOAM import mapDistribute, Pstream
               mapDistribute.distribute( Pstream.defaultCommsType.fget(), 
                                         distMap.schedule(), 
                                         distMap.constructSize(), 
                                         distMap.subMap(),       #what to send
                                         distMap.constructMap(), #what to receive
                                         nbrIntFld() ) 
               
               # Swap to obtain full local values of neighbour K*delta
               nbrKDelta = nbrField.K()*nbrPatch.deltaCoeffs()
              
               mapDistribute.distribute( Pstream.defaultCommsType.fget(), 
                                         distMap.schedule(), 
                                         distMap.constructSize(), 
                                         distMap.subMap(),       #what to send
                                         distMap.constructMap(), #what to receive
                                         nbrKDelta() ) 
               
               myKDelta = self.K()*self.patch().deltaCoeffs()
               
               # Calculate common wall temperature. Reuse *this to store common value.
                              
               Twall = ( myKDelta*intFld +  nbrKDelta*nbrIntFld ) / ( myKDelta + nbrKDelta )

               # Assign to me
               from Foam.finiteVolume import fvPatchScalarField
               fvPatchScalarField.ext_assign( self, Twall )
               mapDistribute.distribute( Pstream.defaultCommsType.fget(),
                                         distMap.schedule(),
                                         nbrField.size(),
                                         distMap.constructMap(),     # reverse : what to send
                                         distMap.subMap(),
                                         Twall() )
               
               fvPatchScalarField.ext_assign( nbrField, Twall )
               pass
               
            # Switch between fixed value (of harmonic avg) or gradient
            # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            nFixed = 0
               
            #Like snGrad but bypass switching on refValue/refGrad.
            normalGradient = ( self-intFld )*self.patch().deltaCoeffs()
            
            if self.debug: 
              Q = ( self.K() * self.patch().magSf() * normalGradient() ).gSum()
              ext_Info ()<< "solidWallMixedTemperatureCoupledFvPatchScalarField::" << "updateCoeffs() :"\
                         << " patch:" << self.patch().name()<< " heatFlux:" << Q << " walltemperature "\
                         << " min:" << self.gMin() << " max:" << self.gMax() << " avg:" << self.gAverage() << nl
              pass           

            for i in range( self.size() ):
               # if outgoing flux use fixed value.
               if normalGradient()[i] < 0.0:
                  self.refValue()[i] = self[i] 
                  self.refGrad()[i] = 0.0  # not used
                  self.valueFraction()[i] = 1.0 
                  nFixed+=1
                  pass
               else:
                  self.refValue()[i]=  0.0  # not used
                  self.refGrad()[i] = normalGradient()[i] 
                  self.valueFraction()[i] =  0.0 
                  pass
              
                        
            from Foam.OpenFOAM import ext_reduce, sumOp_label
                        
            nFixed = ext_reduce( nFixed, sumOp_label() )
            self.fixesValue_ = ( nFixed > 0 )
            
            if (self.debug):
               from Foam.OpenFOAM import returnReduce
               nTotSize = returnReduce(self.size(), sumOp_label())
               ext_Info() << "solidWallMixedTemperatureCoupledFvPatchScalarField::" << "updateCoeffs() :" \
                          << " patch:" << self.patch().name() << " out of:" << nTotSize << " fixedBC:" << nFixed \
                          << " gradient:" << nTotSize-nFixed << nl
               pass                 
            
            mixedFvPatchScalarField.updateCoeffs( self )
            
            pass
        except Exception, exc:
            import sys, traceback
            traceback.print_exc( file = sys.stdout )
            raise exc
    def updateCoeffs( self ) :
        try:
            if self.updated() :
                return
            
            from Foam.meshTools import directMappedPatchBase
            mpp = directMappedPatchBase.ext_refCast( self.patch().patch() )
            
            nbrMesh = mpp.sampleMesh()

            from Foam.finiteVolume import fvMesh
            nbrPatch = fvMesh.ext_refCast( nbrMesh ).boundary()[ mpp.samplePolyPatch().index() ]
            
            # Force recalculation of mapping and schedule
            distMap = mpp.map()
            
            intFld = self.patchInternalField()
            
            from Foam.finiteVolume import volScalarField
            nbrField = solidWallMixedTemperatureCoupledFvPatchScalarField.ext_refCast( volScalarField.ext_lookupPatchField( nbrPatch, self.neighbourFieldName_ ) )
            
            #Swap to obtain full local values of neighbour internal field
            nbrIntFld = nbrField.patchInternalField()
            
            from Foam.OpenFOAM import mapDistribute, Pstream
            mapDistribute.distribute( Pstream.defaultCommsType.fget(), 
                                      distMap.schedule(), 
                                      distMap.constructSize(), 
                                      distMap.subMap(),       #what to send
                                      distMap.constructMap(), #what to receive
                                      nbrIntFld() )
            
            # Swap to obtain full local values of neighbour K*delta
            nbrKDelta = nbrField.K()*nbrPatch.deltaCoeffs()
            mapDistribute.distribute( Pstream.defaultCommsType.fget(), 
                                      distMap.schedule(), 
                                      distMap.constructSize(), 
                                      distMap.subMap(),       #what to send
                                      distMap.constructMap(), #what to receive
                                      nbrKDelta() ) 
            
            myKDelta = self.K()*self.patch().deltaCoeffs()
            
            # Both sides agree on
            # - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
            # - gradient    : (temperature-fld)*delta
            # We've got a degree of freedom in how to implement this in a mixed bc.
            # (what gradient, what fixedValue and mixing coefficient)
            # Two reasonable choices:
            # 1. specify above temperature on one side (preferentially the high side)
            #    and above gradient on the other. So this will switch between pure
            #    fixedvalue and pure fixedgradient
            # 2. specify gradient and temperature such that the equations are the
            #    same on both sides. This leads to the choice of
            #    - refGradient = zero gradient
            #    - refValue = neighbour value
            #    - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())
            
            self.refValue().ext_assign( nbrIntFld )
            self.refGrad().ext_assign( 0.0 )
            self.valueFraction().ext_assign( nbrKDelta / ( nbrKDelta + myKDelta() ) )
            
            mixedFvPatchScalarField.updateCoeffs( self )


            if self.debug: 
              Q = ( self.K() * self.patch().magSf() * self.snGrad() ).gSum()


              ext_Info ()<< patch().boundaryMesh().mesh().name()  << ":" \
                         << patch().name() << ':' << self.dimensionedInternalField().name() << " <- " \
                         << nbrMesh.name() << ':' << nbrPatch.name() << ':' << self.dimensionedInternalField().name() << " :" \
                         << " heat[W]:"  << Q << " walltemperature "\
                         << " min:" << self.gMin() << " max:" << self.gMax() << " avg:" << self.gAverage() << nl
              pass           
            pass
        except Exception, exc:
            import sys, traceback
            traceback.print_exc( file = sys.stdout )
            raise exc