#
# Python script for performing CFX Profile Mapping using the ANSYS Physics
# Coupling mapping functionality.
#

def interpolateVariables(sourcePath,targetPath,outputFilePrefix,targetRegions,varNames):
    import Commands
    for index, regionName in enumerate(targetRegions):
        for varName, fileIndex in varNames.items():
            Commands.SetState(ObjectPath = sourcePath + '/Variable:TransferVariable',
                              State = {'Name' : varName})
            Commands.SetState(ObjectPath = targetPath + '/Variable:TransferVariable',
                              State = {'Name' : varName})
            Commands.ImportResults()
            Commands.Interpolate()
            axdtFileName = (outputFilePrefix + "_" + str(index) + "_" + fileIndex
                            + ".axdt")
            Commands.ExportAXDTFile(ParticipantName = 'Target',
                                    RegionName = regionName,
                                    VariableName = varName,
                                    FilePath = axdtFileName)

def setQuantityType(quantityType):
    import Commands
    Commands.SetState(ObjectPath = sourcePath + '/Variable:TransferVariable',
                      State = {'QuantityType' : quantityType, 'Name' : 'None'})
    Commands.SetState(ObjectPath = targetPath + '/Variable:TransferVariable',
                      State = {'QuantityType' : quantityType, 'Name' : 'None'})

vectorQuantityType = 'Profile Preserving Vector'
scalarQuantityType = 'Profile Preserving Scalar'

path = '/FLUX/PhysicsCoupling/CouplingParticipant:'
sourcePath = path + 'Source'
targetPath = path + 'Target'
SetState(ObjectPath = sourcePath, State = dict())
SetState(ObjectPath = targetPath, State = dict())

noneVarState = {'Name': 'None', 'QuantityType': 'Dimensionless'}
SetState(ObjectPath = sourcePath + '/Variable:None', State = noneVarState)
SetState(ObjectPath = targetPath + '/Variable:None', State = noneVarState)

SetState(ObjectPath = sourcePath + '/Communication',
         State = {'CommunicationMode' : 'FileIO', 'FilePath' : sourceFile})
SetState(ObjectPath = targetPath + '/Communication',
         State = {'CommunicationMode' : 'FileIO', 'FilePath' : targetFile})

setQuantityType(scalarQuantityType)

regionPrefix = 'region-'

sourceRegionList = []
for index, regionName in enumerate(sourceRegions):
    prefixedName = regionPrefix + str(index)
    regionState = {'Name' : regionName,
                   'Topology' : '2',
                   'InputVariables' : ['None'],
                   'OutputVariables' : ['TransferVariable']}
    SetState(ObjectPath = sourcePath + '/Region:' + prefixedName,
             State = regionState)
    sourceRegionList.append(prefixedName)

targetRegionList = []
for index, regionName in enumerate(targetRegions):
    prefixedName = regionPrefix + str(index)
    regionState = {'Name' : regionName,
                   'Topology' : '2',
                   'InputVariables' : ['TransferVariable'],
                   'OutputVariables' : ['None']}
    SetState(ObjectPath = targetPath + '/Region:' + prefixedName,
             State = regionState)
    targetRegionList.append(prefixedName)

interfaceName = 'Interface0'
interfacePath = '/FLUX/PhysicsCoupling/CouplingInterface:' + interfaceName + '/'

sideOneState = {'CouplingParticipant' : 'Source',
                'RegionList' : sourceRegionList}
SetState(ObjectPath = interfacePath + 'Side:One', State = sideOneState)

sideTwoState = {'CouplingParticipant' : 'Target',
                'RegionList' : targetRegionList}
SetState(ObjectPath = interfacePath + 'Side:Two', State = sideTwoState)

ImportRegions()
CalculateMappingWeights()

wtsDiags = GetWeightsDiagnostics()
targetDiags = wtsDiags.get(interfaceName,{}).get('Target')
if targetDiags:
    undefinedVal = 'UNDEFINED'
    elementsMapped = (targetDiags.get('ElementsMappedUsing',{}).
                      get('SurfaceShapeFunction',undefinedVal))
    nodesMapped = targetDiags.get('MappedNodesFraction',undefinedVal)
    areaMapped = targetDiags.get('MappedAreaFraction',undefinedVal)
    with open(diagnosticsFile, 'w') as f:
        f.write(str(elementsMapped) + "\n")
        f.write(str(nodesMapped) + "\n")
        f.write(str(areaMapped) + "\n")

if scalarNames:
    interpolateVariables(sourcePath,targetPath,outputFilePrefix,targetRegions,scalarNames)
if vectorNames:
    setQuantityType(vectorQuantityType)
    interpolateVariables(sourcePath,targetPath,outputFilePrefix,targetRegions,vectorNames)
