Comparative Characterization of Electronic Packaging Materials through Steady State Thermal Conductivity Measurements by John Franklin Maddox, Jr. A thesis submitted to the Graduate Faculty of Auburn University in partial ful llment of the requirements for the Degree of Master of Science Auburn, Alabama August 9, 2010 Keywords: thermal conductivity, thermal resistance, delamination, thermal adhesive, pressure sensitive adhesive, epoxy, alumina granules Copyright 2010 by John Franklin Maddox, Jr. Approved by Roy W. Knight, Co-Chair, Assistant Professor of Mechanical Engineering Sushil H. Bhavnani, Co-Chair, Professor of Mechanical Engineering Jeyhoon M. Khodadadi, Professor of Mechanical Engineering Abstract The decreasing feature size and increasing power generation of modern electronic devices have created a need for increasingly e ective and e cient thermal management solutions to remove the high heat uxes being generated. The complexity of these devices makes it di cult to model the e ects of changing a single component on the system as a whole and often necessitates the use of experimental measurements when comparing alternative solutions. In harsh environments, including high shock and vibration, magnetic devices such as transformer coils are potted to enhance thermal performance and provide mechanical pro- tection. One potting compound frequently used is epoxy containing alumina particles. A nominally isotropic and uniform potting compound consisting of approximately 70 to 80% by volume 14-28 mesh (0.6 to 1.2 mm across) alumina granules in low viscosity epoxy was tested to determine its thermal properties. Examination by optical microscopy revealed signi cant variation in volume fraction of alumina particles by location. The speci c heat and thermal conductivity of the compound were measured using a Di erential Scanning Calorimeter and a comparative cut bar apparatus based on ASTM D 5470. The thermal properties were found to vary with time, location, and temperature; with the speci c heat ranging from 1:00 J=g K 14% at 25 C to 1:22 J=g K 12% at 125 C and an apparent thermal conduc- tivity of 2:56 W=m K 23%. Users of such compounds should be aware that the thermal properties are not necessarily constant in time or uniform, and assuming that they are could lead to signi cant errors when modeling their performance. Steady state thermal conductivity measurements were used to compare printed circuit boards (PCB) manufactured from the same design by di erent vendors and the e ect of vias lled with an epoxy versus un lled vias on the thermal resistance of a PCB. It was found ii that the thermal resistance of the PCBs varied as much as 30% between vendors and that the PCBs with the un lled vias performed slightly better than those with the lled vias. A non-destructive method was used to determine the e ects of thermal cycling on the thermal performance of a PCB attached to an aluminum substrate with a thermal adhesive. This method allows for a comparison of the thermal performance of various thermal interface materials (TIM) in an industrial application. Testing was done on FR4 and Flex boards, both with and without overmolding, attached using pressure sensitive adhesive and an alternative proprietary adhesive. Baseline measurements were taken, then the boards were cycled from -40 to 125 C on a 90-minute cycle with 15-minute dwells at the target temperatures. It was found that both adhesives showed an increase in thermal conductivity, possibly due to curing, and delamination occurred at 17 out of 35 locations with the alternative adhesive within the rst 1500 cycles while no delamination occurred with the PSA. iii Acknowledgments I would like to thank my advisory committee: Dr. Roy W. Knight, Dr. Sushil H. Bhav- nani, and Dr. Jeyhoon M. Khodadadi, with special thanks to Dr. Knight and Dr. Bhavnani for their constant encouragement and guidance throughout my graduate career. I would like to thank the Center for Advanced Vehicle and Extreme Environment Electronics (CAVE3) for funding my work. I would like to thank my friends and colleagues who have helped me on a daily basis. Most of all I would like to thank my mother, father, and daughter for their endless love, encouragement, support, and patience. I could not have completed this work without their help. iv Table of Contents Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii List of Abbreviations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Potting Compounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 Printed Circuit Boards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Thermal Interface Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1 Conduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.1 Thermal Conductivity . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.2 Thermal Resistance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1.3 Conduction in a Composite . . . . . . . . . . . . . . . . . . . . . . . 12 2.2 Measurement of Thermal Conductivity . . . . . . . . . . . . . . . . . . . . . 17 2.2.1 Steady-State Measurement of Thermal Conductivity . . . . . . . . . 17 2.2.2 Transient Measurement of Thermal Conductivity . . . . . . . . . . . 22 2.2.3 Measurement of Thermal Interface Materials . . . . . . . . . . . . . . 26 2.3 Potting Compounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.4 Thermal Adhesives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3 Experimental Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.1 Volume Fraction Measurement through Image Processing . . . . . . . . . . . 31 3.2 Speci c Heat Measurement with a Di erential Scanning Calorimeter . . . . . 31 v 3.3 Apparent Thermal Conductivity Measurement with a Comparative Cut Bar Apparatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.4 Thermal Resistance Measurement with a Comparative Cut Bar Apparatus . 36 3.5 In Situ Thermal Resistance Measurement . . . . . . . . . . . . . . . . . . . . 37 3.6 Test Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.6.1 Alumina Granule/Epoxy Potting Compound . . . . . . . . . . . . . . 42 3.6.2 PCB Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.6.3 Thermal Adhesives . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4 Experimental Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.1 Volume Fraction of Alumina . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2 Speci c Heat of an Alumina/Epoxy Composite . . . . . . . . . . . . . . . . . 52 4.3 Apparent Thermal Conductivity of Alumina/Epoxy Composite . . . . . . . . 53 4.4 Comparison of PCB Thermal Performance . . . . . . . . . . . . . . . . . . . 58 4.5 E ects of Thermal Cycling on Thermal Adhesives . . . . . . . . . . . . . . . 62 4.5.1 Clamped Junction Resistance . . . . . . . . . . . . . . . . . . . . . . 64 4.5.2 Unclamped Junction Resistance . . . . . . . . . . . . . . . . . . . . . 65 4.5.3 Overmolding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.1 Alumina Granule/Epoxy Composite Characterization . . . . . . . . . . . . . 73 5.2 PCB Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.3 In Situ Thermal Adhesive Measurement . . . . . . . . . . . . . . . . . . . . 75 Appendices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 A Junction Resistance Measurements . . . . . . . . . . . . . . . . . . . . . . . . . 84 B Thermocouple Calibration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 C Uncertainty Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 C.1 Volume Fraction Measurement through Image Processing . . . . . . . . . . . 93 C.2 Speci c Heat Measurement with a Di erential Scanning Calorimeter . . . . . 94 vi C.3 Thermal Conductivity Measurement with a Comparative Cut Bar Apparatus 94 C.4 In Situ Thermal Resistance Measurement of a PCB Attached to an Aluminum Substrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 C.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 D Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 D.1 Volume Fraction Measurement through Image Processing . . . . . . . . . . . 100 D.2 Apparent Thermal Conductivity Measurement with a Comparative Cut Bar Apparatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 D.2.1 Data Acquisition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 D.2.2 Data Reduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 D.3 In Situ Thermal Resistance Measurement of a PCB Attached to an Aluminum Substrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 D.3.1 Data Acquisition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 D.3.2 Data-Reduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 vii List of Figures 1.1 Printed circuit board diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1 One dimensional conduction through a layered medium modeled with an equiv- alent thermal circuit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2 Qualitative illustration of the paths for heat transfer across the interface between two solids. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.3 One dimensional conduction through a layered medium modeled with an equiv- alent thermal circuit including contact resistances. . . . . . . . . . . . . . . . . 10 2.4 The introduction of a TIM between two surfaces can reduce the overall thermal interface resistance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.5 Homogeneous spherical ller particles randomly distributed within a homoge- neous matrix material. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.6 Conductive chain formed by contacting ller particles . . . . . . . . . . . . . . . 14 3.1 Image used to determine the volume fraction of epoxy . . . . . . . . . . . . . . 32 3.2 Guarded heater apparatus used to measure thermal conductivity. . . . . . . . . 33 3.3 Schematic of comparative cut bar apparatus . . . . . . . . . . . . . . . . . . . . 36 3.4 Fixture for measuring the junction resistance of a circuit board attached to an aluminum backing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 viii 3.5 Mounting con gurations for measuring junction resistance. . . . . . . . . . . . . 39 3.6 PCB mounted in junction resistance measurement xture. . . . . . . . . . . . . 39 3.7 Insulation used to minimize heat losses to the environment junction resistance measurement xture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.8 Typical thermal resistance data . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 3.9 Cross section of alumina granule/epoxy sample block. . . . . . . . . . . . . . . . 43 3.10 Schematic representation of an alumina/epoxy cast block . . . . . . . . . . . . . 44 3.11 Alumina/epoxy samples used for the apparent thermal conductivity measurements 44 3.12 Front side of PCB con gurations Q and V samples. . . . . . . . . . . . . . . . . 45 3.13 Back side of PCB con gurations Q and V samples. . . . . . . . . . . . . . . . . 46 3.14 Front side of PCB con guration QB samples. . . . . . . . . . . . . . . . . . . . 46 3.15 Back side of PCB con guration QB samples. . . . . . . . . . . . . . . . . . . . . 47 3.16 Front side of PCB con gurations U and F samples. . . . . . . . . . . . . . . . . 47 3.17 Back side of PCB con gurations U and F samples. . . . . . . . . . . . . . . . . 48 3.18 Circuit layout for test vehicle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.19 Images of aluminum substrate attached to PCB. . . . . . . . . . . . . . . . . . . 50 4.1 Micrographs illustrating the variation in volume fraction of alumina . . . . . . . 52 4.2 Speci c heat of a sample measured with a DSC . . . . . . . . . . . . . . . . . . 53 4.3 Typical speci c heat values for di erent locations. . . . . . . . . . . . . . . . . . 54 ix 4.4 Images of sample after performing a conductivity test . . . . . . . . . . . . . . . 54 4.5 Changes in the material after being exposed to 125 C . . . . . . . . . . . . . . . 56 4.6 Micrographs of curing surface e ects . . . . . . . . . . . . . . . . . . . . . . . . 56 4.7 Cross sections of lled and un lled vias . . . . . . . . . . . . . . . . . . . . . . . 61 4.8 Thermal resistances of FR4 boards prior to cycling . . . . . . . . . . . . . . . . 63 4.9 Thermal cycling pro le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 4.10 Average junction resistance with cycling . . . . . . . . . . . . . . . . . . . . . . 64 4.11 Average change in junction resistance with cycling . . . . . . . . . . . . . . . . 65 4.12 Comparison of junction resistance for clamped and unclamped boards . . . . . . 66 4.13 Percent change in junction resistance of boards without clamping . . . . . . . . 67 4.14 Percentage of locations where delamination has occurred. . . . . . . . . . . . . . 68 4.15 Image of adhesive failure caused by thermal cycling in ALT adhesive . . . . . . 69 4.16 Front and back images of overmolding A . . . . . . . . . . . . . . . . . . . . . . 71 4.17 Front and back images of overmolding B showing material removed. . . . . . . . 72 D.1 LabView front panel for comparative cut bar temperature measurement. . . . . 103 D.2 LabView block diagram for comparative cut bar temperature measurement. . . 104 D.3 LabView front panel for thermocouple measurement. . . . . . . . . . . . . . . . 105 D.4 LabView block diagram for thermocouple measurement. . . . . . . . . . . . . . 105 x D.5 LabView front panel for comparative cut bar heat generation. . . . . . . . . . . 106 D.6 LabView block diagram for comparative cut bar heat generation. . . . . . . . . 106 D.7 LabView front panel for comparative cut bar load measurement. . . . . . . . . . 106 D.8 LabView block diagram for comparative cut bar load measurement. . . . . . . . 107 D.9 Front panel for junction resistance measurement data acquisition. . . . . . . . . 129 D.10 Block diagram for junction resistance measurement data acquisition, Part 1 of 2. 130 D.11 Block diagram for junction resistance measurement data acquisition, Part 2 of 2. 130 xi List of Tables 3.1 PCB and thermal adhesive con gurations tested . . . . . . . . . . . . . . . . . . 49 4.1 Volume fraction of alumina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2 Apparent thermal conductivity values of alumina/epoxy composite . . . . . . . 57 4.3 Thermal impedance measurements for PCB con gurations Q and V. . . . . . . 58 4.4 Apparent thermal conductivity measurements for PCB con gurations Q and V. 59 4.5 Thermal impedance measurements for PCB con guration QB. . . . . . . . . . . 59 4.6 Apparent thermal conductivity measurements for PCB con guration QB. . . . . 59 4.7 Thermal impedance measurement for PCB con gurations U and F. . . . . . . . 60 4.8 Apparent thermal conductivity measurements for PCB con gurations U and F. 60 A.1 Thermal resistance values for clamped PSA FLEX boards. . . . . . . . . . . . . 84 A.2 Thermal resistance values for unclamped PSA FLEX boards. . . . . . . . . . . . 85 A.3 Thermal resistance values for clamped PSA FR4 boards. . . . . . . . . . . . . . 86 A.4 Thermal resistance values for unclamped PSA FR4 boards. . . . . . . . . . . . . 87 A.5 Thermal resistance values for clamped ALT FR4 boards. . . . . . . . . . . . . . 88 A.6 Thermal resistance values for unclamped ALT FR4 boards. . . . . . . . . . . . . 89 A.7 Thermal resistance values for PSA OM-A boards. . . . . . . . . . . . . . . . . . 90 A.8 Thermal resistance values for PSA OM-B boards. . . . . . . . . . . . . . . . . . 90 C.1 Tabulated uncertainties of measured quantities. . . . . . . . . . . . . . . . . . . 99 xii List of Abbreviations Acronyms ALT alternative adhesive CTE coe cient of thermal expansion DSC di erential scanning calorimeter FR4 ame retardant 4 NTC negative thermal coe cient PBGA plastic ball grid array PCB printed circuit board PDF probability density function PIL Python Imaging Library PSA pressure sensitive adhesive RGB red, green, and blue color model RTD resistance temperature detector TIM thermal interface material English letter symbols a radius of ller particle, m cp speci c heat, kJ=kg K xiii I electrical current, A k thermal conductivity, W=m K L length, m n number of measurements P power dissipated, W Q energy, J q heat, W R thermal resistance, K=W Re electrial resistance, t1=2 time corresponding to Tmax=2, s T temperature, K t time, s V voltage, V Greek letter symbols thermal di usivity, m2=s skin constant, W=m2 K i uncertainty of i, has the same units as i T temperature di erence, K apparent thermal conductivity, W=m K ! dimensionless time (scaled Fourier number), 2 t=L2 xiv volume fraction of ller particle, % density, kg=m3 dimensionless temperature, T(L;t)=Tmax Superscripts 00 per unit area, m 2 000 per unit volume, m 3 Subscripts bot bottom metering block cal calibration curve cond conduction cont contact conv convection f ller particle FM ux meter j junction jx junction to reference point lower lower bound m matrix material max maximum mb metering bar xv meas measured value s sample top top metering block upper upper bound x reference point xvi Chapter 1 Introduction The removal of heat from electronic components has become an increasingly important aspect of electronics packaging in recent years. As electronic devices have become smaller and more powerful, they have also started to generate more heat in a smaller area. Because of this trend, thermal management solutions are having to become increasingly more e cient and e ective in order to handle the escalating heat ux being generated. If the heat is not e ectively removed from a device, it will cause the temperature of the device to rise excessively, which negatively impacts the performance and reliability of the device. At higher temperatures, processors operate less e ciently and require more power. This causes a decrease in computational speed as well as a decrease in battery life for mobile devices. Additionally, large temperature gradients create stresses which can decrease the life of the device. The di erence in the coe cient of thermal expansion (CTE) between dissimilar mate- rials causes shear stresses to be generated during normal operation of an electronic device. The cyclic nature of these stresses causes fatigue at the joints, which leads to cracking and ultimately failure. Minimizing the temperature change experienced by a device will diminish the e ects of CTE stresses and thus lead to improved reliability. The heat generated in an electronic device must eventually be rejected to the environ- ment. This process is enhanced in a number of ways, usually with a heat sink being attached to the heat producing components in a device. However, the thermal resistance from the components to the heat sink can become a bottleneck if measures are not taken to decrease the contact resistance between the two. While the contact resistance could be decreased by pressing one surface against the other with su cient force, this is not optimal from a 1 reliability or manufacturing point of view. Additionally, the irregular shapes of some elec- tronic components make it di cult to attach a heat sink. One solution to these problems is to incorporate an intermediate medium which helps to transfer the heat from the electrical component to the heat sink that interacts with the environment. 1.1 Potting Compounds Electronic components with irregular form factors and components exposed to harsh environments are often encapsulated in a potting compound. The encapsulant is usually made out of a thermally conductive dielectric material. Some such materials which are being increasingly used as potting compounds are ceramic oxide lled polymers. The motivation for this is that the composite retains the electrical and thermal properties of the ceramic while keeping the mechanical properties of the polymer, which allows the compound to be easily incorporated into the manufacturing processes used to package electronics. One common polymer that is used is epoxy, the properties of which can be adjusted by altering the components and curing agents used. Epoxy containing alumina granules is frequently used to encapsulate magnetic devices since it has a relatively high dielectric constant and thermal conductivity while still being conformal enough, prior to curing, to be easily applied during assembly. The higher thermal conductivity of the potting compound helps to remove the heat generated by the device, while the mechanical support supplied by the hardened resin helps to protect the device, especially in harsh environments with high shock and vibration. In order to properly model the performance of a device encapsulated in a potting com- pound, it it necessary to have accurate values for the thermophysical properties of the com- posite. However, these properties can be di cult to predict, especially when the ller parti- cles are packed closely enough to interact with one another. This study will experimentally 2 determine the properties of one such composite consisting of Stycast W-19 epoxy impreg- nated with T64 tabular alumina which is used to encapsulate a power transformer attached to a liquid cooled heat sink. 1.2 Printed Circuit Boards Many modern electronic devices are assembled on printed circuit boards (PCB), which provide signal connection, electrical isolation, radiation insulation, and mechanical support. Most PCBs consist of multiple copper layers separated by layers of insulation. The copper layers can be signal layers, which route the signals between the components, or ground/power planes, which are used to supply a common ground and reference voltage the components in the assembly. The insulation between the copper layers is usually provided by alternating layers of pre-impregnated, or pre-preg, woven glass ber with uncured epoxy, and core, woven glass ber with cured epoxy and copper foil bonded to each side. The term stack-up is used to refer to the number, order, and thickness of the layers. The stack-up will usually be vertically symmetric so as to avoid warping due to CTE e ects. A diagram of a six layer stack up is shown in Figure 1.1. The di erent layers in a PCB are connected through plated holes called vias. These vias can be designed to transmit signals, power, and/or heat. There are three main type Copper Core Pre-preg Pre-preg Pre-preg Core Through hole via Figure 1.1: Diagram of a printed circuit board with 6 layers of copper separated by alter- nating layers of pre-preg and core with a through hole via. 3 of vias: through hole vias, blind vias, and buried vias. A through hole via is one that goes from the top of a PCB to the bottom through all the layers. A blind via is one that starts at either the top or the bottom and goes through one or more layers but does not go all the way through. A buried via is one that goes through one or more interior layers but does not extend through either the top of the bottom layer of the PCB. This study will look at the e ects of lling through hole copper plated vias with an epoxy on the thermal resistance of a PCB. It is common for an electronics manufacturer to send a PCB design to a third party vendor for fabrication. However, the decisions made and the equipment used by the vendor can have signi cant e ects on the nal properties and performance of the PCB. This study will measure at the di erence in the thermal properties of PCBs fabricated from three vendors using the same PCB design. 1.3 Thermal Interface Materials When attaching a heat sink to an electronic component with a planar surface it is com- mon to use a thermal interface material (TIM) to decrease the interfacial thermal resistance. Some TIMs in use today are soft metals, thermal greases, epoxy resins, pressure sensitive adhesive tapes (PSA), phase change materials, and elastomer pads [1, 2]. The properties of these materials are often enhanced by the addition of judiciously selected particles to increase the bulk thermal conductivity of the material. The use of a thermal adhesive as a TIM gives the added bene t of securing the two surfaces together without the need for external clamping. This reduces the complexity of a device by reducing the number of components; simpli es the manufacturing, as adhesives are relatively easy to apply when compared to the alternatives; and increases the reliability of the device by absorbing thermally induced stresses. Adhesives, both electrically conductive and thermally conductive, are used in the assembly of many automotive electronics [3]. 4 When used as a TIM in these applications, it is necessary that the adhesive exhibit reliable performance both mechanically and thermally. The e ects of aging [4] and thermal cycling [5{9] on the mechanical strength of various adhesives have been well documented in the literature. However, there is less information about the e ects of aging and thermal cycling on the thermal performance of these adhesives. Since degradation in thermal performance can ultimately lead to electrical failure, it is important to understand how the properties of a TIM will change during the life cycle of a product. This study will look at how the thermal performance of two competing thermal adhesives are e ected by accelerated aging through the use of thermal cycling. 5 Chapter 2 Background 2.1 Conduction The molecules within a medium, be it solid, liquid, gas, or plasma, are constantly in- teracting with one another. As this occurs, the molecules transfer kinetic energy, or heat, back and forth between themselves. Since the motion of the molecules is random, there is no directional preference to the energy transfer, but rather the net ow of energy is from regions of high energy to regions of low energy, by a process called conduction. Temperature is a measure of the average kinetic energy of the particles within a medium, with higher tempera- tures corresponding to higher concentrations of energy. With this de nition of temperature, conduction is a di usive transfer of heat driven by a temperature gradient, governed by the equation cp@T@t +r q00 q000 = 0 (2.1) where is the density, cp is the speci c heat, T is the temperature, t is the time, q00 is the heat ux vector, and q000 is the heat generation. 2.1.1 Thermal Conductivity Conduction within a medium can be described by the Fourier?s law, q00 = krT; (2.2) which relates the heat ux to the temperature gradient through the use of a proportionality constant, k, called thermal conductivity. The thermal conductivity is a material property 6 which can vary with temperature and is usually, but not necessarily, isotropic. Thermal conductivity typically increases with temperature for gases and decreases with temperature for solids and liquids. For a one dimensional case, the Fourier?s law reduces to q00 = kdTdx: (2.3) 2.1.2 Thermal Resistance It is often convenient to view the ow of heat as being analogous to the ow of electricity. In an electrical circuit, the ow of electrons is driven by a voltage potential, V, and the rate of ow, I, is limited by the electrical resistance, Re, as governed by the equation Re = VI: (2.4) In this sense, the temperature gradient is analogous to the voltage potential and the ow of heat is analogous to the current. At this point, a term called thermal resistance can be introduced to be analogous to the electrical resistance, where thermal resistance is the ability of a material to resist the ow of heat. Following the analogy, the thermal resistance, R, can be related to the temperature and heat ow as R = Tq (2.5) where T is the temperature di erence between two points which drives the ow of heat, q. Conduction Resistance For the case of one dimensional steady state conduction, i.e. a plane wall, the thermal conductive resistance, Rcond, is de ned by rearranging Eq. (2.3) to be of the from of Eq. (2.5), Rcond = Tq = LkA (2.6) 7 or, in terms of heat ux, RcondA = Tq00 = Lk (2.7) where L is the distance between the temperatures of T and A is the cross-sectional area normal to the heat ow. The circuit analogy is particularly useful when analyzing composite systems in which an equivalent thermal circuit can be used to model heat owing through multiple mediums in either series or parallel. For example, one dimensional conduction through three consecutive plane walls with di ering properties can be modeled as three thermal resistances in series, as shown in Figure 2.1. Figure 2.1: One dimensional conduction through a layered medium modeled with an equiv- alent thermal circuit. Contact Resistance An additional thermal resistance, called thermal contact resistance, exists at the inter- face between two solids and is primarily due to roughnesses e ects at the contacting surfaces. All real surfaces have asperities which cause them to have a roughness. This being the case, when two materials are in contact with one another, the contact is not uniform across the surfaces but rather it occurs only at discrete locations. This results in gaps being inter- spersed between contact points along the interface. These gaps are usually lled with air, although they could also be lled with another uid or evacuated. 8 The heat being transfered across the interface can take one of two paths. The rst path is through the contact areas in which the conductive ow is primarily governed by the thermal conductivities of the two materials. The second path is across the gaps. Since it is usually the case that the gaps are too small for bulk uid motion to take place, the modes for heat transfer across the gaps are limited to conduction through the uid and radiation. The two paths can be viewed as parallel thermal resistances with a combined equivalent thermal resistance, Rcont. Since the conductivity of the uid is usually lower than that of the contacting materials, more of the heat will tend to ow through the contact areas than across the gaps, as illustrated in Figure 2.2. Figure 2.2: Qualitative illustration of the paths for heat transfer across the interface be- tween two solids. The example of the three layered plane wall can now be revisited and expanded to include the contributions of the contact resistances between the layers, as shown in Figure 2.3. The overall value of the contact resistance can be minimized through two main ap- proaches: maximizing the ratio of contact area to gap area and increasing the heat transfer across the gaps. The most obvious rst step to decreasing the contact resistance is to make the two surfaces as smooth as possible. This causes there to be a larger number of smaller asperities, which leads to more contact points, thus increasing the contact area to gap area 9 Figure 2.3: One dimensional conduction through a layered medium modeled with an equiv- alent thermal circuit including contact resistances. ratio. Additionally, decreasing the height of the asperities on the two surfaces results in thinner gaps, which in turn decreases the resistance to conduction across the gaps. Another step that can be taken is to increase the joint pressure of the surfaces, which has the same net e ect as decreasing the roughness of the surfaces. Pressing the two materials together will cause the surfaces to deform, either plastically or elastically depending of the properties of the materials and the pressure being applied. As the amount of deformation increases, the contact area increases and the gap thickness decreases, thus leading to a lower thermal resistance. A third way is to decrease the thermal resistance across the gaps is by increasing the thermal conductivity of the uid within them. This is usually done through the use of an interfacial uid, such as thermal grease. Thermal Interface Materials An alternative approach to minimizing thermal contact resistance is to introduce an additional layer of a third material between the two contacting surfaces. This third material is referred to as a thermal interface material (TIM). A TIM is usually made out of a soft, malleable material which will conform to the surfaces of the harder materials. This causes 10 the contact to gap ratio to be higher between the TIM and each of the surfaces than it would have been between the surfaces without the TIM. The introduction of the TIM replaces one contact resistance (Rcont;1-2) with two contact resistances and a conductive resistance (Rcont;1-TIM + Rcond;TIM + Rcont;TIM-2), as illustrated in Figure 2.4. Therefore, in order for the TIM to be bene cial, it must be the case that Rcont;1-TIM +Rcond;TIM +Rcont;TIM-2 ? def show(self): print(?\nSample #: %s? % self.number) print(?Filename: %s? % self.filename) print(?Tested: %s? % time.strftime(?%a %-1m/%-1d/%y at %-1I:%M %p?,\ self.test_date)) print(?Thickness: %f? % self.thickness) print(?Temperature of bottom interface: %f%s? % \ (self.T_interface_bottom, my.dgc)) print(?Temperature of top interface: %f%s? % (self.T_interface_top,\ my.dgc)) print(?Mean Sample Temp: %f%s? % (self.mean_T, my.dgc)) print(?Thermal conductivity: k_sample + k_contact = %f W/mK? % \ self.k_total) print(?Heat flux at bottom interface: %f W/m^2? % self.flux_bottom) print(?Heat flux at top interface: %f W/m^2? % self.flux_top) print(?Orientation: ? + self.extra_info) class Results(list): ???Organization class for conductivity measurements??? def __init__(self): self = [] def __call__(self, n=?all?, temp=?all?, labelside=?all?, force=435): l = self[:] 115 if n != ?all?: if isinstance(n,tuple) or isinstance(n,list): l = [i for i in l if i.number in n] else : l = [i for i in l if i.number == n] if force != ?all?: if isinstance(force, tuple) or isinstance(force, list): l = [i for i in l if i.force in force] else : l = [i for i in l if i.force == force] if temp != ?all?: if temp == ?room? or temp == 25: l = [i for i in l if 20 < i.mean_T < 30] elif temp == 50: l = [i for i in l if 45 < i.mean_T < 55] elif temp == 75: l = [i for i in l if 70 < i.mean_T < 80] elif temp == 100: l = [i for i in l if 95 < i.mean_T < 105] else: print(?The mean temperature of Sample %s is %.2f%s, \ which does not fall into any of the specified categories? \ % (i.number, i.mean_T, my.dgc)) if labelside != ?all?: if labelside in [?cold?, ?Cold?, ?COLD?, ?c?, ?C?, ?up?, ?Up?, \ ?UP?, ?u?, ?U?]: 116 l = [i for i in l if i.extra_info == ?Label-Cold?] elif labelside in [?hot?, ?Hot?, ?HOT?, ?h?, ?H?, ?down?, \ ?Down?, ?d?, ?D?]: l = [i for i in l if i.extra_info == ?Label-Hot?] return l class kCalculation(): """A k value calculated from the data collected """ def __init__(self, samples, verbose=False): ???Find the least-squares solution for the thermal conductivity for the given samples??? samples = my.flatten(samples) A = [] b = [] for sample in samples: A.append([2, sample.thickness]) b.append(sample.delta_T/sample.flux) Rc, k_inv = np.linalg.lstsq(A,b)[0] k = 1/k_inv self.value = k self.Rc = Rc self.k_inv = k_inv self.samples = samples 117 def __add__(self, other): return self.value + other def __mul__(self, other): return self.value * other def __div__(self, other): return self.value / other def __truediv__(self, other): return self.value / other def __repr__(self): return str(n(self.value, digits=3)) def details(self): print(?\n\tLeast-Squares solutions?) print(?Thermal Conductivity: k = %.2f W/mK? % self.value) print(?Thermal Contact Resistance: Rc = %f m%sK/W? % (self.Rc, \ my.sq)) for sample in self.samples: 118 Rtot = sample.delta_T/sample.flux Rl = sample.thickness * self.k_inv print(?\n\t%s? % sample) print(?Total Thermal Resistance: Rtot = %f m%sK/W? % (Rtot, \ my.sq)) print(?Thermal Interface Resistance (Contact) [each face]: \ Rc = %f m%sK/W? % (self.Rc, my.sq)) print(?Sample Thermal Resistance (Conductive): Rl = L/k = \ %f m%sK/W? % (Rl, my.sq)) print(?Contribution of Contact Resistance: Rc/Rtot = %f? % \ (2*self.Rc/Rtot)) print(?Contribution of Conductive Resistance: Rl/Rtot = %f? \ % (Rl/Rtot)) print(??) def CalibrationCalculations(CalibrationCSVFile): ???Produce Thermocouple objects which contain the calibration curves for each of the thermocouples used??? ### Calibration Calculations ### # Import the calibration measurements from the .csv file CalibrationMeasurements = np.array(my.read_csv_file(CalibrationCSVFile)) # Convert the first column resistance readings into temperatures TempStandard = map(ti.temp_from_thermistor, CalibrationMeasurements[:,0]) # Create a dictionary to store the thermocouples in 119 TC = {} # Create an iterator for the number of thermocouples (note: the # thermocouples have stickers with letters - # A corresponds to 1, B to 2, ...) NofTCs = range(1, len(CalibrationMeasurements[0])) # Process each additional column after the first in the csv file as # thermcouples for i in NofTCs: # Instantiate a thermoucouple object TC[i]=Thermocouple() # define attibutes of the thermocouple TC[i].slope, TC[i].intercept, TC[i].rsq, TC[i].Sxy, TC[i].Sxx, \ TC[i].xm, TC[i].u_precision, TC[i].u_scale, TC[i].u = \ sc.Calibrate(CalibrationMeasurements[:,i], TempStandard) # store the slope and the intercept as the calibration coefficients: # this will be used to evaluate the TC[i].cal() method (note: # additional coefficents could be supplied here to get a quadratic, # cubic, ... calibration curve, however the sc.Calibrate function # currently only returns a linear fit because it uses # scipy.stats.linregress TC[i].coeffs = [TC[i].slope, TC[i].intercept] return TC def BuildSampleList(sampleNumbers, temperature, extrainfo, force=400): ???Yields a list of sample objects meeting the given criteria??? 120 l = [] for number in sampleNumbers: l.append(tests(n=number, temp=temperature, lableside=extrainfo,\ force=force)) return my.flatten(l) def ProcessData(DataDir,CalibrationCSVFile, verbose=False): ???Process the data in DataDir using the thermocouple calibration data in CalibrationCSVFile??? StartDir = os.getcwd() CalibrationCalculations(CalibrationCSVFile) os.chdir(DataDir) files = [file for file in os.listdir(os.curdir) if (file !=?.directory?\ and ?.swp? not in file)] files.sort() tests = Results() for i, file in enumerate(files): obj = ConductivityMeasurement(file, verbose=verbose) tests.append(obj) os.chdir(StartDir) if verbose: print(tests) return tests 121 jfm.py import csv import numpy as np import scipy.special # for the inverse student t function import string from sage.misc.latex import * from sage.misc.functional import numerical_approx import cPickle import os import sys import cStringIO import operator def flatten(x): """flatten(sequence) -> list Returns a single, flat list which contains all elements retrieved from the sequence and all recursively contained sub-sequences (iterables). Examples: >>> [1, 2, [3,4], (5,6)] [1, 2, [3, 4], (5, 6)] >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)]) [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10] """ 122 result = [] for el in x: #if isinstance(el, (list, tuple)): if hasattr(el, "__iter__") and not isinstance(el, basestring): result.extend(flatten(el)) else: result.append(el) return result class Regression(): """A regression object. Call it with the syntax reg = Regression(x_values, y_values[, degree=1]) degree=1 will produce a linear fit degree=2 will produce a quadratic fit and so on """ def __init__(self, x_values, y_values, degree=1): self.coeffs = np.polyfit(x_values, y_values, degree) self.intercept = np.polyval(self.coeffs, 0) self.p = np.poly1d(self.coeffs) self.slope = np.polyder(self.p) yhat = [self.p(z) for z in x_values] ybar = sum(y_values)/len(y_values) ssreg = sum([(yihat-ybar)**2 for yihat in yhat]) 123 sstot = sum([(yi-ybar)**2 for yi in y_values]) self.rsq = ssreg/sstot def __call__(self, value): return np.polyval(self.coeffs, value) def __str__(self): return self.p.__str__() def read_csv_file(filename): ???Reads a CSV file and returns it as a list of rows. Numbers will be coerced into either int or float type depending on the presence of a decimal??? data = [] for row in csv.reader(open(filename)): data.append(row) floatdata = [map(safe_int_float,row) for row in data] return floatdata def safe_int_float(string): ???convert a string to either an int or a float if appropriate, i.e. safe_int_float(?a?) >>> ?a? safe_int_float(?1?) >>> 1 safe_int_float(?1.?) >>> 1.0 124 safe_int_float(?3.14?) >>> 3.14??? try: result = int(string) except ValueError: try: result = float(string) except ValueError: result = string return result def tinv(nu, p): ???Student?s t inverse cumulative distribution function t = tinv(nu, p) computes the inverse of Student?s t cdf for degrees of freedom nu=n-1 and a confidence interval of p=1-conf_intv i.e. p=0.1 for a 90% confidence interval??? # the negative sign is to correct for the format of the raw function return -scipy.special.stdtrit(nu, p) ### Constants ### dg = u?\N{DEGREE SIGN}? dgc = u?\N{DEGREE SIGN}?+?C? 125 pm = u?\N{PLUS-MINUS SIGN}? sq = u?\N{SUPERSCRIPT TWO}? cu = u?\N{SUPERSCRIPT THREE}? cdot = u?\N{MIDDLE DOT}? mult = u?\N{MULTIPLICATION SIGN}? SensorCalibration.py import scipy import numpy as np import jfm as my from scipy import stats class CalibrationCurve(): ???An object class for storing information about a calibration curve??? def __init__(self, measured, standard, confidence_interval=0.95, \ order=1): slope, intercept, r_value, p_value, std_err = stats.linregress(\ measured,standard) rsq = r_value**2 n = len(measured) nu = n-1 calibrated=scipy.polyval([slope,intercept],measured) xm = np.mean(measured) Sxxsq = scipy.sum([(i - xm)**2 for i in measured]) Sxx = scipy.sqrt(Sxxsq) Syx = scipy.sqrt(sum([(standard[i]-calibrated[i])**2 for i,v in \ 126 enumerate(standard)])/(n-2)) t_a_nu = st(nu,confidence_interval) U_offset = (t_a_nu*Syx) * scipy.sqrt(1/n + xm**2/Sxxsq) U_scale = (t_a_nu * Syx) / (Sxx) U = [U_offset, U_scale] self.slope = slope self.intercept = intercept self.p = np.poly1d([slope, intercept]) self.rsq = rsq self.Syx = Syx self.Sxx = Sxx self.xm = xm self.u_offset = U_offset self.u_scale = U_scale self.u = U def __call__(self, value): return (np.polyval([self.slope, self.intercept], value), \ np.polyval([self.u_scale, self.u_offset], value)) def __str__(self): return ?f(x) = %f x + %f %s [%f x + %f]? % (self.slope, \ self.intercept, my.pm, self.u_scale, self.u_offset) def Calibrate(measured,standard,confidence_interval=0.95,order=1): ???Returns the calibration curve coefficients, R-squared valued, 127 Deviation from the standard (S_xy), and the calibrated uncertainty from a list of measured values and a list of true values. slope, intercept, Rsq, Syx, Sxx, xm, U_offset, U_scale, U = Calibrate(meausred, standard, confidence interval = 0.95, order = 1)??? slope, intercept, r_value, p_value, std_err = \ stats.linregress(measured,standard) rsq = r_value**2 n = len(measured) nu = n-1 calibrated=scipy.polyval([slope,intercept],measured) xm = np.mean(measured) Sxxsq = scipy.sum([(i - xm)**2 for i in measured]) Sxx = scipy.sqrt(Sxxsq) Syx = scipy.sqrt(sum([(standard[i]-calibrated[i])**2 for i,v in \ enumerate(standard)])/(n-2)) t_a_nu = my.tinv(nu,confidence_interval) U_offset = (t_a_nu*Syx) * scipy.sqrt(1/n + xm**2/Sxxsq) U_scale = (t_a_nu * Syx) / (Sxx) U = [U_offset, U_scale] return slope, intercept, rsq, Syx, Sxx, xm, U_offset, U_scale, U 128 D.3 In Situ Thermal Resistance Measurement of a PCB Attached to an Alu- minum Substrate D.3.1 Data Acquisition Figure D.9: Front panel for junction resistance measurement data acquisition. 129 Figure D.10: Block diagram for junction resistance measurement data acquisition, Part 1 of 2. Figure D.11: Block diagram for junction resistance measurement data acquisition, Part 2 of 2. 130 D.3.2 Data-Reduction JunctionResistanceCalculations.py import os, string, numpy, scipy.stats, re, pylab, matplotlib, pylab import matplotlib.pyplot as plt from matplotlib import rcParams DefaultBaseDirectory=?Path/To/Directory/? class BoardList(dict): """List for storing Board objects""" def types(self): temp_list=[] for board in self.values(): temp_list.append(board.type) return list(set(temp_list)) def bytype(self,type=?All?): Types=self.types() temp_list=[] for i in range(len(Types)): temp_list.append([]) for board in self.values(): if board.type == Types[i]: temp_list[i].append(board) temp_list[i].sort() if type == ?All?: 131 return sorted(temp_list) return sorted(temp_list[Types.index(type)]) def all(self): return sorted(self.values()) class Board(): """board object: has attributes of .cycles, .name, and .type""" def __init__(self, type, name): self.type=type self.name=name self.cycles=CycleList() def __str__(self): return self.name def __repr__(self): return ?? def __cmp__(self,other): if self.type != other.type: return cmp(self.type,other.type) if (?ALT? in self.name and ?ALT? in other.name) or \ (?PSA? in self.name and ?PSA? in other.name): return cmp(int(re.search(?(\d+)?,self.name).group(1)),\ int(re.search(?(\d+)?,other.name).group(1))) if ?-? in self.name and ?-? in other.name: return cmp(int(re.search(?-(\d+)?,self.name).group(1)),\ 132 int(re.search(?-(\d+)?,other.name).group(1))) class CycleList(list): """list of cycles: is an attribute of a board object as .cycles: has attributes .clamped(), .unclamped(), .numbers, and .units""" def __init__(self): self=[] def __str__(self): l=?? for cycle in sorted(self): l+=cycle.name+?\n? return l def __repr__(self): l=[] for cycle in sorted(self): l.append(cycle.name) return ?, ?.join(l) def numbers(self): l=[] for cycle in sorted(self): l.append(int(re.search(?(\d+)(.+)?,cycle.name).group(1))) return l 133 def units(self): return re.search(?(\d+)(.+)?,self[0].name).group(2).replace(? ?,??) def clamped(self): return [cycle for cycle in self if ? U? not in cycle.name] def unclamped(self): return [cycle for cycle in self if ? U? in cycle.name] class Cycle(): """cycle object: is a part of a CycleList() list: has attributes: .tr1 - Thermal resistance at location 1 .tr2 - Thermal resistance at location 2 .rsq1 - R squared value for the line fit used to determine the thermal resistance at location 1 .rsq2 - R squared value for the line fit used to determine the thermal resistance at location 2 .name - a string containing the name of the cycle derived from the name of the directory from which the Excel files were imported, i.e. 500 Cycles U .number - the number""" def __init__(self,cycle_number,tr_readings): self.tr1=tr_readings[0] self.tr2=tr_readings[1] self.rsq1=tr_readings[2] self.rsq2=tr_readings[3] 134 self.td1=tr_readings[4] self.td2=tr_readings[5] self.name=cycle_number def __str__(self): return self.name def __repr_(self): return ?? def __cmp__(self, other): return cmp(int(re.search(?(\d+)?,self.name).group(1)),\ int(re.search(?(\d+)?,other.name).group(1))) def number(self): return int(re.search(?(\d+)(.+)?,self.name).group(1)) def ReadFromExcel(filename): """Import data from an Excel file""" # Open the file for reading file=open(filename) # Read the data from the file and store it into a variable called data # it is stored as a list of strings with each string contanining one # line from the original file data=file.readlines(); # Close the file file.close() # Split the strings into individual elements so that the data will be 135 # a 2-d array rather than a 1-d list for i,v in enumerate(data): data[i]=string.split(data[i]) for I,V in enumerate(data[i]): data[i][I]=float(data[i][I]) return data def ExtractTemperatureColumns(data): """Select the desired colums from the imported data""" # transpose the data for that each column is an element in the array datatrans=numpy.transpose(data) # return columns 5, 6, 10, and 11 return numpy.array([datatrans[4],datatrans[5],datatrans[9],\ datatrans[10]]) def FilterMeasurements(data): """Remove faulty or unnecessary readings from the list""" #Create a dummy list for putting data into new_array=[] #Check each value and exclude it if it is outside a reasonable range for v in data: if v>0 and v<100: new_array=numpy.append(new_array,v) return new_array[-20:] 136 def AverageData(data): """Return the difference between the average reading of each thermistor/thermocouple pair""" # Average of (thermistor reading - thermocouple reading) try: TempDrop1=numpy.mean(FilterMeasurements(data[0])-\ FilterMeasurements(data[1])) except ValueError: TempDrop1=-1 try: TempDrop2=numpy.mean(FilterMeasurements(data[2])-\ FilterMeasurements(data[3])) except ValueError: TempDrop2=-1 return numpy.array([TempDrop1,TempDrop2]) def ProcessCycle(verbose=False): """Process the excel files in the current directory to get a thermal resistance for the current cycle""" TemperatureDrops = numpy.zeros((5,2)) power = x = [0, 0.5, 1.0, 1.5, 2.0] res = lambda c,y,x: y-c*x for i,file in enumerate([?W00.XLS?,?W05.XLS?,?W10.XLS?,?W15.XLS?,\ ?W20.XLS?]): 137 data=ReadFromExcel(file) data=ExtractTemperatureColumns(data) TemperatureDrops[i]=(AverageData(data)) if -1. in TemperatureDrops[:,0]: TR1 = ? ? rsq1 = ? ? else: y=TemperatureDrops[:,0]-TemperatureDrops[0,0] fit=scipy.optimize.leastsq(res, [6], args=(y,x)) TR1 = fit[0] rsq1 = 1-sum([res(fit[0],y[i],x[i]) for i in range(1,5)])**2/\ sum(y[1:-1])**2 if -1. in TemperatureDrops[:,1]: TR2 = ? ? rsq2 = ? ? else: y=TemperatureDrops[:,1]-TemperatureDrops[0,1] fit=scipy.optimize.leastsq(res, [6], args=(y,x)) TR2 = fit[0] rsq2 = 1-sum([res(fit[0],y[i],x[i]) for i in range(1,5)])**2/\ sum(y[1:-1])**2 return [TR1, TR2, rsq1, rsq2, TemperatureDrops[:,0], \ TemperatureDrops[:,1]] def CalculateClampedVsUnclamped(boards): """Calculates the absolute and percent differnece between the clamped 138 and unclamped reading for the non-overmolded boards""" for group in [?ALT FR4?,?PSA FR4?,?PSA FLEX?]: for board in boards.bytype(group): board.trd1={} for index,cycle in enumerate(board.cycles.clamped()[2:]): if cycle.tr1 != ? ? and \ board.cycles.unclamped()[index].tr1 != ? ?: diff=board.cycles.unclamped()[index].tr1-cycle.tr1 board.trd1[cycle.name]={?Difference?:diff,\ ?Percent Difference?:diff/cycle.tr1} board.trd2={} for index,cycle in enumerate(board.cycles.clamped()[2:]): if cycle.tr2 != ? ? and \ board.cycles.unclamped()[index].tr2 != ? ?: diff=board.cycles.unclamped()[index].tr2-cycle.tr2 board.trd2[cycle.name]={?Difference?:diff,\ ?Percent Difference?:diff/cycle.tr2} def ImportData(basedir=DefaultBaseDirectory,verbose=False): """Import the the data from excel files and categorize it by the location of the files following the pattern where the first subfolder is the type of the board, the second subfolder is the name of the board, the third subfolder is the number of cycles and the fourth subfolder contains the excel file with the meausrements""" # save the location of the current directory 139 CurrentDirectory = os.getcwd() # move into the base directory os.chdir(basedir) # then into the data directory os.chdir(?Data?) # Initialize a variable containing an empty board list, which #is an oject of the class BoardList() boards=BoardList() # define a list a directories to ignore dir_exclude_list=[?CSV Files?,?Figures?,?November 08?,?TeX?] # iterate through a loop for directories not in dir_exclude_list for directory in os.listdir(os.getcwd()): if (directory in dir_exclude_list) or \ (os.path.isdir(directory) == False): continue # assign the name of the current directory to be the type of board BoardType=directory # move into the directory for the current type os.chdir(directory) # debugging if verbose: print BoardType # iterate through for each subdirectory in the current directory for subdir in os.listdir(os.getcwd()): # assign the name of the current directory to be the name of # the board BoardName=subdir # create a new object of the type Board() and append it to the 140 # variable boards boards[BoardName]=Board(BoardType, BoardName) # move into the directory for the current board os.chdir(subdir) # debugging if verbose: print BoardName # iterate through for each subdirectory for subsubdir in sorted(os.listdir(os.getcwd())): # assign the name of the current directory to be the # name of the current cycle CycleNumber=subsubdir # debugging if verbose: print CycleNumber # move into the directory for the cycle os.chdir(subsubdir) # debugging if verbose: print os.getcwd() # append an object Cycle() to the attribute cycles # of the current board boards[BoardName].cycles.append(\ Cycle(CycleNumber,ProcessCycle())) # move up a directory to process the next cycle os.chdir(os.pardir) # sort the imported cycles boards[BoardName].cycles.sort() # move up a directory to process the next board os.chdir(os.pardir) 141 # move up a directory to process the next board type os.chdir(os.pardir) # move back to the original directory os.chdir(CurrentDirectory) # clean up variables del(subdir, subsubdir, BoardType, BoardName) # fix any boards that were tested with the wires connected in the # wrong order for cycle in [boards[?ALT8?].cycles[1],\ boards[?PSA-5 FLEX?].cycles[8]]: cycle.tr1, cycle.tr2 = cycle.tr2, cycle.tr1 # Calculate Percent Differences in thermal resistances CalculateClampedVsUnclamped(boards) # return a list of boards with the thermal resistances # as attributes stored as a 2-D list in the location # board.cycles = [[tr1,tr2,rsq1,rsq2],[tr1,tr2,rsq1,rsq2],...] return boards def CreateTables(boards,basedir=DefaultBaseDirectory,pub=False): """Apply the CreateTRsLatexTable() function for each type of board and save the resulting files to the appropriate location""" if pub: os.chdir(ipackdir) table_dir=?Tables? else: os.chdir(basedir) 142 table_dir=os.path.join(?Results?,?Tables?) list_of_tables=[] if not os.path.exists(table_dir): os.makedirs(table_dir) os.chdir(table_dir) for board_group in boards.bytype(): filename=?%sThermalResistancesTable.tex? % board_group[0].type.replace(? ?,??) CreateTRsLatexTable(board_group, filename=filename) list_of_tables.append(filename) os.chdir(os.pardir) f=open(?Tables.tex?,?w?) for table in list_of_tables: f.writelines(?\\input{Tables/%s}\n? % table) f.close() os.chdir(basedir) def ExtractTRsForCSVFile(Boards): """Build a comma separated string for use in CreateCSVFiles()""" l=[] for board in Boards: l.append([board.name,?TR1?]) for cycle in board.cycles.clamped(): if cycle.tr1 == ? ?: l[-1].append(? ?) else: l[-1].append(?%f? % cycle.tr1) for cycle in board.cycles.unclamped(): if cycle.tr1 == ? ?: l[-1].append(? ?) 143 else: l[-1].append(?%f? % cycle.tr1) l[-1]=?,?.join(l[-1]) l.append([board.name,?TR2?]) for cycle in board.cycles.clamped(): if cycle.tr2 == ? ?: l[-1].append(? ?) else: l[-1].append(?%f? % cycle.tr2) for cycle in board.cycles.unclamped(): if cycle.tr2 == ? ?: l[-1].append(? ?) else: l[-1].append(?%f? % cycle.tr2) l[-1]=?,?.join(l[-1]) return ? \n?.join(l) def CreateCSVFiles(boards,basedir=DefaultBaseDirectory): """Creates a CSV file with the processed thermal resistances""" OriginalDirectory=os.getcwd() os.chdir(basedir) csv_dir=os.path.join(?Results?,?CSV Files?) if not os.path.exists(csv_dir): os.makedirs(csv_dir) os.chdir(csv_dir) for board_group in boards.bytype(): filename=?%s.csv? % board_group[0].type f=open(filename,?w?) f.write(ExtractTRsForCSVFile(board_group)) f.close() f=open(?AllBoards.csv?,?w?) 144 f.write(ExtractTRsForCSVFile(boards.all())) f.close() os.chdir(OriginalDirectory) def FindStats(Boards,Exclude=??,verbose=False,ClampedThenUnclamped=False): """Returns two arrays. The first array give the average resistance for each cycle and the second array gives the corresponding standard deviation. The convention for this fucntion is to use the options: Exclude=?Unclamped? - to get the values fo the clamped boards Exclude=?Clamped? to get the values for the unclamped boards.""" data=[] datacheck=True for board in Boards: templist=[] for cycle in board.cycles: if Exclude==?Unclamped? and ? U? in cycle.name: continue if Exclude==?Clamped? and ? U? not in cycle.name: continue elif cycle.tr1 == ? ?: datacheck=False else: templist.append(cycle.tr1) if datacheck: data.append(templist) datacheck=True templist=[] for cycle in board.cycles: if Exclude==?Unclamped? and ? U? in cycle.name: continue if Exclude==?Clamped? and ? U? not in cycle.name: continue if cycle.tr2 == ? ?: datacheck=False 145 else: templist.append(cycle.tr2) if datacheck: data.append(templist) datacheck=True data=numpy.array(data).transpose() average=[numpy.mean(data[i]) for i in range(len(data))] deviation=[numpy.std(data[i]) for i in range(len(data))] return average, deviation def DelaminationData(Boards): """Display the number of boards for each degree of delamination for each cycle. This is to be used in the interactive shell and is not currently incorporated into any other function definitions""" # Criteria for delamination full_delam = 0.5 partial_delam =0.25 delam_data={} for group in Boards.bytype(): if ? OM? in group[0].type: continue delam_data[group[0].type]={} for index,cycle in enumerate(group[0].cycles.clamped()[2:]): number_of_full_delam=0 number_of_partial_delam=0 number_of_no_delam=0 for board in group: 146 if board.cycles.clamped()[index+2].tr1 != ? ? and \ board.cycles.unclamped()[index].tr1 != ? ? and \ board.name != ?PSA-5 FLEX?: pd=board.trd1[cycle.name][?Percent Difference?] if pd >= full_delam: number_of_full_delam+=1 elif pd >= partial_delam: number_of_partial_delam+=1 else: number_of_no_delam+=1 if board.cycles.clamped()[index+2].tr2 != ? ? and \ board.cycles.unclamped()[index].tr2 != ? ?: pd=board.trd2[cycle.name][?Percent Difference?] if pd >= full_delam: number_of_full_delam+=1 elif pd >= partial_delam: number_of_partial_delam+=1 else: number_of_no_delam+=1 delam_data[group[0].type][cycle.name]=(number_of_full_delam,\ number_of_partial_delam,number_of_no_delam) return delam_data if __name__ == ?__main__?: boards = ImportData() CreateCSVFiles(boards) 147