Hello Dr. Wheeler,

'dx' is actually the thickness of the thermal contact region.  It is not
the volume of the cell.  If it were a volume, the ratio
dx/mesh._cellDistances would not be dimensionless.  I was seeking a thermal
contact region of zero thickness (dx=0), giving a true thermal contact
resistance.

I let this thread drop because the Salazar paper I referenced gave me
expressions for effective thermal conductivity and effective thermal
diffusivity, and this allowed me to arrive at a reasonable-looking FiPy
result for transient thermal behavior.  My result still deviates a bit from
the exact solution at steady state, and this deviation persists despite
mesh refinement, but I am busy with other things and have called it good
enough for now.

OK, I won't leave you hanging.  Here is the code I was working on.  Maybe
you or someone else can spot a defect that would explain why the code does
not exactly replicate the steady state solution.  Another thing to do is:
compare the transient result with the transient result obtained another way
(ANSYS etc).  I used to have an analytical solution for the transient
laying around, but threw it out in a pile of papers (oops).

#I am trying to look at the script by Wheeler at
#https://www.mail-archive.com/fipy@nist.gov/msg02640.html
#and modify it in view of Guyer as in
#https://www.mail-archive.com/fipy@nist.gov/msg02641.html
#now instead of a steady state problem, do a transient problem

import fipy as fp
import numpy as np
from IPython import embed
import sys
import os
import pygmsh
import meshio
import csv
import matplotlib.pyplot as plt
from shutil import copyfile
#head
def
get_uniform_mesh_with_pygmsh(L_Sample,L_Substrate,cellSize,write_to_msh_file=False):
    '''
    figure it out in ipython
    ref: https://github.com/nschloe/pygmsh/blob/master/test/test_pacman.py
    '''
    geom = pygmsh.built_in.Geometry()

    #geom.add.point?  see what the input arguments are in ipython using ?
    p1=geom.add_point([0,0,0],cellSize)
    p2=geom.add_point([L_Substrate,0,0],cellSize)
    p3=geom.add_point([L_Substrate+L_Sample,0,0],cellSize)

    l1=geom.add_line(p1,p2)
    l2=geom.add_line(p2,p3)

    #not much point in doing physical groups since have no way to transmit
this info to 1D fipy mesh
    # geom.add_physical_point(p1,label='SubstrateEnd')
    # geom.add_physical_point(p2,label='TCR')
    # geom.add_physical_point(p3,label='SampleEnd')

    # geom.add_physical_line(l1,label='Substrate')
    # geom.add_physical_line(l2,label='Sample')

    points, cells, point_data, cell_data, field_data =
pygmsh.generate_mesh(geom)

    if write_to_msh_file:

mesh=meshio.Mesh(points=points,cells=cells,point_data=point_data,cell_data=cell_data,field_data=field_data)
        meshio.write('TCR01.msh',mesh)

    mesh=get_fipy_1D_mesh_from_points(points)

    return mesh

#head
#head
if __name__=='__main__':
    #substrate is copper and sample is pure tin

    rho_Sample=6980.  #use wolfram alpha to get the density of copper;
kg/m^3
    cp_Sample=227.  #use wolfram alpha to get the specific heat of copper;
J/kg/K
    k_Sample=59.6  #W/m/K
    D_Sample=k_Sample/rho_Sample/cp_Sample
    L_Sample=2e-6  #m  SETTING

    rho_Substrate=8960.  #use wolfram alpha to get the density of copper;
kg/m^3
    cp_Substrate=384.4  #use wolfram alpha to get the specific heat of
copper; J/kg/K
    k_Substrate=381.8  #W/m/K
    D_Substrate=k_Substrate/rho_Substrate/cp_Substrate
    L_Substrate=10*L_Sample  #m  SETTING

    #model an interface thermal resistance between copper and solder, with
the solder being soldered to the copper
    R_TIM_unit_area=2e-6  #K/(W/m2)  SETTING

    TIM_target_dT=1.  #K  SETTING
    HeatFlux=TIM_target_dT/R_TIM_unit_area  #W/m^2  heat flux is determined
by TIM_target_dT


    #using a uniform mesh:
    cellSize=.1*L_Sample  #SETTING


mesh=get_uniform_mesh_with_pygmsh(L_Sample,L_Substrate,cellSize,write_to_msh_file=False)


    #make sure you like the mesh before doing a run
    #sys.exit()


    diffCoeff = fp.FaceVariable(mesh=mesh, value=D_Substrate)

    diffCoeff.setValue(D_Sample,where=(mesh.faceCenters[0]>=L_Substrate))

    xCenters,=mesh.cellCenters

    #thermal conductivity of a cell if it's R" were R_TIM_unit_area:
    Kcontact=1./R_TIM_unit_area*mesh._cellDistances  #type is
numpy.ndarray; [W/m/K]

    Kcell=fp.CellVariable(mesh=mesh,value=k_Substrate)
    Kcell.setValue(k_Sample,where=(xCenters>=L_Substrate))

    Kavg = Kcell.harmonicFaceValue  #a FaceVariable

    #see 20180717EffectiveProperties.xoj
    Keff=Kcontact * Kavg / (Kavg + Kcontact)  #W/m/K
    rho_times_cp_eff=.5*(rho_Substrate*cp_Substrate+rho_Sample+cp_Sample)
#TODO ask on fipy mailing list as to how to express dAP1/(dAP1+dAP2) in
fipy syntax; the factor of .5 here is only approximate

    diffCoeff.setValue(Keff/rho_times_cp_eff, where=(mesh.faceCenters[0] ==
L_Substrate))

    v = fp.CellVariable(mesh=mesh)
    v.constrain(0, where=mesh.facesLeft)
    v.faceGrad.constrain(HeatFlux / k_Sample, where=mesh.facesRight)

    #follow examples at
https://www.ctcms.nist.gov/fipy/examples/diffusion/generated/examples.diffusion.mesh1D.html#module-examples.diffusion.mesh1D
    eq1=fp.TransientTerm()==fp.DiffusionTerm(coeff=diffCoeff)  #implicit
    dtExplicitLimit_Substrate = cellSize**2 / (2 * D_Substrate)
    dtExplicitLimit_Sample = cellSize**2 / (2 * D_Sample)

dtExplicitLimit_InterfaceCell=cellSize**2/(2*Keff.value.mean()/rho_times_cp_eff)
#play with Keff in ipython; .mean seems close enough to what you want

dt=10*min([dtExplicitLimit_Substrate,dtExplicitLimit_Sample,dtExplicitLimit_InterfaceCell])
#SETTING

    #viewer=fp.Viewer(vars=(v,),datamin=0,datamax=10.)
    viewer=fp.Viewer(vars=(v,))

    TJumpAtInterfaceExpected=HeatFlux*R_TIM_unit_area

TJumpInBarNoInterfaceExpected=HeatFlux*(L_Substrate/k_Substrate+L_Sample/k_Sample)

TJumpInBarExpected=TJumpAtInterfaceExpected+TJumpInBarNoInterfaceExpected

    blurb='''
    at steady state:
    expected T jump at interface is %.2E
    expected T jump in bar with no interface is %.2E
    expected total T jump in bar is %.2E
    hit return to continue
    ''' %
(TJumpAtInterfaceExpected,TJumpInBarNoInterfaceExpected,TJumpInBarExpected)

    #run with --inline if you have weave working
    steps = 15000  #SETTING
    plotEvery=100  #SETTING
    saveDataEvery=200  #SETTING

    #TODO need code to stop when at thermal steady state

    times=[]
    rod_dTs=[]

    outFilenameBase='20180717UniformMesh04'  #SETTING

    outFilename=outFilenameBase+'.csv'

    assert (not os.path.exists(outFilename)), '%s already exists on disk;
this script requires that you manually update outFilenameBase'

    with open(outFilename,'w') as csvfile:
        csvWriter = csv.writer(csvfile, delimiter=' ',quotechar='|',
quoting=csv.QUOTE_MINIMAL)
        for step in range(steps):

            eq1.solve(var=v,dt=dt)

            if step%plotEvery==0:
                print 'step is %d of %d\n' % (step,steps)
                viewer.plot()

            if step%saveDataEvery==0:
                #saving the temperature drop across the entire rod vs time:
                times.append(step*dt)
                rod_dTs.append(v.value[-1]-v.value[0])

                csvWriter.writerow([step*dt,v.value[-1]-v.value[0]])  #TODO
am looking at values at cell centers; really want face values

    raw_input(blurb)

    fig, ax = plt.subplots()
    ax.plot(times,rod_dTs)

    ax.set(xlabel='time (s)', ylabel='temperature drop across entire rod,
K')

    ax.grid()

    fig.savefig(outFilenameBase+'.png')
    plt.show()

    raw_input('hit enter to continue')

    #make a copy of this script with a new name so you have a good record
of what produced the result
    #copyfile(src,dst)

copyfile('ModifyWheelerInViewOfGuyer20130517TransientVersionImplicit03.py',outFilenameBase+'.py')

    #don't forget to run with --inline if you have weave installed and
working


On Mon, Jul 23, 2018 at 11:30 AM Daniel Wheeler <daniel.wheel...@gmail.com>
wrote:

> On Tue, Jul 17, 2018 at 4:43 PM, Drew Davidson <davidson...@gmail.com>
> wrote:
> >
> > I still need FiPy code for:
> >
> >
> > dAP1/(dAP1+dAP2)
> >
> >
> > and
> >
> >
> > dAP2/(dAP1+dAP2)
> >
> >
> > where dAP1 and dAP2 were distances from cell center to cell face for
> cells
> > on either side of the interface.  If these FiPy expressions are
> unavailable,
> > I would think assuming .5 is going to be OK...
>
> I think it's outlined in the link that you gave.
>
>     Kcontact = hc * mesh._cellDistances
>     Kavg = Kcell.harmonicFaceValue
>     K.setValue(Kcontact * Kavg / (Kavg + Kcontact * (1 - dx /
> mesh._cellDistances)), where=mesh.physicalFaces['thermal contact'])
>
> m._cellDistances is the distance between each cell and `dx` is the
> volume of the cell for a 1D problem.
>
>
>
> --
> Daniel Wheeler
> _______________________________________________
> fipy mailing list
> fipy@nist.gov
> http://www.ctcms.nist.gov/fipy
>   [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
>
_______________________________________________
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]

Reply via email to