Layer

Characterizes the thermal conductivity of a material layer.

Description

The Layer class defines the thermal conductivity of a material layer—whether isotropic, uniaxially anisotropic, or fully anisotropic—and specifies how conductivity is expressed in user inputs. It also handles conversion of user inputs into the tensor representation, which is required by the internal ForwardModel solver.

Supported Representations:

  • Isotropic conductivity: k
  • Transverse and axial conductivities (k⊥, k∥) with
    • Azimuthal and polar axis direction angles: θ_az, θ_pol
    • Unit vector axis direction: v1, v2, v3
  • Principal conductivities (kp1, kp2, kp3) with
    • Euler orientation angles: θa1, θb2, θc3
    • Unit quaternion orientation: q1, q2, q3, q4
    • Vectorized rotation matrix orientation: R11, R21, R31, R12, R22, R32, R13, R23, R33
  • 6-element tensor conductivity: k11, k21, k31, k22, k32, k33

Creation

Syntax

layer = Layer()
layer = Layer(isotropy)
layer = Layer(isotropy,orient)
layer = Layer(isotropy,orient,euler_seq)

Description

layer = Layer() creates a Layer object using the default tensor representation of thermal conductivity.


layer = Layer(isotropy) creates a Layer object with a user-specified isotropy type. Valid only for "isotropic" and "tensor" conductivity representations, since orient must also be specified for "uniaxial" and "principal" cases.


layer = Layer(isotropy,orient) creates a Layer object with a user-specified isotropy type and orientation. Valid only for "uniaxial" and "principal" representations, since orient is not required for "isotropic" or "tensor". If Euler orientation angles are used, euler_seq must also be provided (see next).


layer = Layer(isotropy,orient,euler_seq) creates a Layer object with a user-specified isotropy type, orientation, and Euler angle sequence. Valid only when orient is "euler", since euler_seq is not required for other orientations.

Input Arguments

isotropy - Isotropy type "tensor" (default) | "isotropic" | "uniaxial" | "principal" | IsotropyEnum object

Isotropy type specifies the isotropy level of the layer.

  • "isotropic": For scalar thermal conductivity: k
  • "uniaxial": For 2 principal thermal conductivities: transverse (k⊥) and axial (k∥) </li>
  • "principal": For 3 principal thermal conductivities sorted in descending order: kp1 > kp2 > kp3
  • "tensor": For 6-element thermal conductivity tensor: k11, k21, k31, k22, k32, k33

char and string inputs are *case-insensitive* and may be specified as a unique leading substring of any one of the above listed options.

Data Types: char | string | IsotropyEnum

orient - Orientation type "na" (default) | "azpol" | "uvect" | "euler" | "uquat" | "rotmat" | OrientEnum object

Orientation type specifies the symmetric axis direction (isotropy="uniaxial") or the principal axes orientation (isotropy="principal"). Required only when isotropy equals either "uniaxial" or "principal".

  • "na": No orientation specified
  • "azpol": For representing the symmetric axis direction as azimuthal θ_az and polar θ_pol angles. Valid only when film_isotropy = "uniaxial".
  • "uvect": For representing the symmetric axis direction as a unit vector v1, v2, v3. Valid only when film_isotropy = "uniaxial".
  • "euler": For representing the orientation of the principal axes as Euler angles θa1, θb2, θc3, with a, b, c ∈ {x, y, z}
  • "uquat": For representing the orientation of the principal axes as a unit quaternion q1, q2, q3, q4
  • "rotmat": For representing the orientation of the principal axes as a vectorized rotation matrix R11, R21, R31, R12, R22, R32, R13, R23, R33

char and string inputs are *case-insensitive* and may be specified as a unique leading substring of any one of the above listed options.

Data Types: char | string | OrientEnum

euler_seq - Euler angle sequence "na" (default) | "XYX" | "XYZ" | "XZX" | "XZY" | "YXY" | "YXZ" | "YZX" | "YZY" | "ZXY" | "ZXZ" | "ZYX" | "ZYZ" | SeqEnum object

Euler angle sequence specified as three axes. I.e., computes the rotation matrix as \(\mathbf{R} = \mathbf{R}_a\left(\theta_1\right) \cdot \mathbf{R}_b\left(\theta_2\right) \cdot \mathbf{R}_c\left(\theta_3\right)\), where \(a, b, c \in \left\{x, y, z\right\}\) are the 1st, 2nd, and 3rd characters of the input character array, and:

\( {\mathbf{R}_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{bmatrix}},\, {\mathbf{R}_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{bmatrix}},\, {\mathbf{R}_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix}} \)

Required only when orient equals "euler".

char and string inputs are *case-insensitive* and may be specified as a unique leading substring of any one of the above listed options.

Data Types: char | string | SeqEnum

Properties

Layer properties include validated constructor input arguments as well as the following:

inputStr - toTensor input variable names Read only: string row vector

Since the number of inputs to the toTensor function depends on the arguments specified when the object is created, inputStr provides the names of the toTensor input variables as a string row vector.

Data Type: string </p>

Example: if isotropy == "uniaxial" and orient == "azpol", then inputStr = ["k⊥", "k∥", "θ_az", "θ_pol"], and the user can call layer.toTensor(k⊥,k∥,θ_az,θ_pol) to convert to tensor conductivity representation.

Object Functions

toTensor Converts user inputs to tensor representation

Examples

Constructing a Uniaxially Symmetric Thermal Conductivity Tensor

Layer Creation:

Suppose we have a uniaxially thermally symmetric layer, characterized by:

  • Transverse conductivity (k⊥): conductivity in the plane orthogonal to the axis of symmetry.
  • Axial conductivity (k∥): conductivity along the axis of symmetry.

To orient the axis of symmetry in 3D space, we use azimuthal (θ_az) and polar (θ_pol) angles.

layer = Layer("uni", "azpol") % 'uni' uniquely maps to 'uniaxial'
layer = 
  Layer with properties:

     isotropy: uniaxial
       orient: azpol
    euler_seq: na
     inputStr: ["k⊥", "k∥", "θ_az", "θ_pol"]

Here, the inputStr property tells us that the function toTensor will require four arguments: k⊥, k∥, θ_az, and θ_pol.

Conversion to Tensor with Axis Aligned with the z-axis:

k_perp = 20; % Transverse conductivity
k_par  = 50; % Axial conductivity

az  = 0; % Azimuthal Angle
pol = 0; % Polar Angle

% Convert to 6-element tensor
[k11, k21, k31, k22, k32, k33] = layer.toTensor(k_perp, k_par, az, pol);

K = [k11, k21, k31;
     k21, k22, k32;
     k31, k32, k33]
K = 3x3
    20     0     0
     0    20     0
     0     0    50

Since the symmetry axis aligns with the z-axis, the tensor reduces to a diagonal form:

  • Kxx = K(1,1) = k⊥
  • Kyy = K(2,2) = k⊥
  • Kzz = K(3,3) = k∥

This matches intuition: axial conductivity in the z-direction, transverse conductivity in x– and y-directions.

We get the same result if we orient the axis of symmerty in the -z direction. (The only difference comes from small floating-point errors introduced by evaluating sin⁡(π)).

az  = 0;  % Azimuthal Angle
pol = pi; % Polar Angle

% Convert to 6-element tensor
[k11, k21, k31, k22, k32, k33] = layer.toTensor(k_perp, k_par, az, pol);

K = [k11, k21, k31
     k21, k22, k32
     k31, k32, k33]
K = 3x3
   20.0000         0   -0.0000
         0   20.0000         0
   -0.0000         0   50.0000

Conversion to Tensor w/ Axis Oriented Arbitrarily:

az  = deg2rad(30); % Azimuthal Angle
pol = deg2rad(45); % Polar Angle

% Convert to 6-element tensor
[k11, k21, k31, k22, k32, k33] = layer.toTensor(k_perp, k_par, az, pol);

K = [k11, k21, k31
     k21, k22, k32
     k31, k32, k33]
K = 3x3
   31.2500    6.4952   12.9904
    6.4952   23.7500    7.5000
   12.9904    7.5000   35.0000

Here the conductivity tensor is fully populated with six unique elements, even though the material can be defined by only four parameters (k⊥, k∥, θ_az, θ_pol).

Constructing the Tensor from Principal Conductivities and Euler Angles

Layer Creation:

Suppose we have a material layer with three unique principal conductivities: kp1 > kp2 > kp3.

To orient the principal axes, we use ZYZ Euler angles: θZ1, θY2, and θZ3.

layer = Layer("principal", "euler", "ZYZ")
layer = 
  Layer with properties:

     isotropy: principal
       orient: euler
    euler_seq: ZYZ
     inputStr: ["kp1", "kp2", "kp3", "θZ1", "θY2", "θZ3"]

Here, the inputStr property tells us that the function toTensor will require six arguments: kp1, kp2, kp3, θZ1, θY2, and θZ3.

Conversion to Tensor with Four Different Orientations:

Consider a layer with four grains, each sharing the same principal conductivities but differing in the orientation of their principal axes:

  • Grain 1: [p1,p2,p3] = [x,y,z] (aligned with global coordinate system)
  • Grain 2: [p1,p2,p3] = [y,x,z]
  • Grain 3: [p1,p2,p3] = [z,y,x]
  • Grain 4: Complex orientation

The toTensor function handles the variablility in orientation automatically, returning a tensor for each grain.

kp1 = 10;
kp2 = 5;
kp3 = 2;

% Four orientation angles for each of the four grains
thetaZ1 = deg2rad([0, 90, 0, 30]);
thetaY2 = deg2rad([0, 0, 90, 45]);
thetaZ3 = deg2rad([0, 0, 0, 120]);

% Convert to 6-element tensor
[k11, k21, k31, k22, k32, k33] = layer.toTensor(kp1, kp2, kp3, thetaZ1, thetaY2, thetaZ3);

Each element of the tensor is a 1-by-4 vector. We can display the matrix tensor for each grain as follows:

for i = 1:length(k11)
    fprintf( ...
        "Tensor when ZYZ Euler angles = [%g, %g, %g] deg:", ...
        rad2deg(thetaZ1(i)), rad2deg(thetaY2(i)), rad2deg(thetaZ3(i)) ...
    )
    K = [k11(i), k21(i), k31(i)
         k21(i), k22(i), k32(i)
         k31(i), k32(i), k33(i)]
end
Tensor when ZYZ Euler angles = [0, 0, 0] deg:
K = 3x3
    10     0     0
     0     5     0
     0     0     2

Tensor when ZYZ Euler angles = [90, 0, 0] deg:
K = 3x3
    5.0000    0.0000         0
    0.0000   10.0000         0
         0         0    2.0000

Tensor when ZYZ Euler angles = [0, 90, 0] deg:
K = 3x3
    2.0000         0   -0.0000
         0    5.0000         0
   -0.0000         0   10.0000

Tensor when ZYZ Euler angles = [30, 45, 120] deg:
K = 3x3
    6.6071   -2.7681   -2.6058
   -2.7681    6.2679    0.2633
   -2.6058    0.2633    4.1250

Thus, a single set of principal conductivities can yield multiple grain-specific tensors simply by varying the Euler angles, providing a flexible way to represent anisotropy in a material layer.

Constructing Multiple Tensors w.r.t. Temperature and Orientation

Layer Creation:

Suppose we have a uniaxially thermally symmetric layer, characterized by:

  • Transverse conductivity (k⊥): conductivity in the plane orthogonal to the axis of symmetry.
  • Axial conductivity (k∥): conductivity along the axis of symmetry.

To orient the axis of symmetry in 3D space, we use unit direction vectors: v1, v2, v3

layer = Layer("uni", "uvect") % 'uni' uniquely maps to 'uniaxial'
layer = 
  Layer with properties:

     isotropy: uniaxial
       orient: uvect
    euler_seq: na
     inputStr: ["k⊥", "k∥", "v1", "v2", "v3"]

Here, the inputStr property tells us that the function toTensor will require five arguments: k⊥, k∥, v1, v2, and v3.

Conversion to Tensors w.r.t. Three Temperatures and Two Orientations:

Consider a layer with two grains, each sharing the same principal conductivities but differing in the orientation of their principal axes.

Furthermore, suppose we wish to calculate the tensor at three different temperatures.

Since the orientation of the principal axes is independent of temperature, we obtain a total of six tensors:

     
  Grain 1 Grain 2
Temp 1 K11 K12
Temp 2 K21 K22
Temp 3 K31 K32
k_perp = [20; 25; 30]; % Transverse conductivity at T1, T2, and T3
k_par  = [50; 45; 40]; % Axial conductivity at T1, T2, and T3

% Unit direction vectors for grains 1 and 2
v1 = [1, 1/sqrt(3)];
v2 = [0, 1/sqrt(3)];
v3 = [0, 1/sqrt(3)];

% Convert to 6-element tensor
[k11, k21, k31, k22, k32, k33] = layer.toTensor(k_perp, k_par, v1, v2, v3);

Each element of the tensor is a 3-by-2 matrix. We can display the matrix tensor for each temperature-grain combination as follows:

for Ti = 1:size(k11, 1)
    for Oi = 1:size(k11, 2)
        fprintf( ...
            "Tensor when k⊥ = %g, k∥ = %g, and v = [%g, %g, %g]", ...
            k_perp(Ti), k_par(Ti), v1(Oi), v2(Oi), v3(Oi) ...
        )
        K = [k11(Ti, Oi), k21(Ti, Oi), k31(Ti, Oi)
             k21(Ti, Oi), k22(Ti, Oi), k32(Ti, Oi)
             k31(Ti, Oi), k32(Ti, Oi), k33(Ti, Oi)]
    end
end
Tensor when k⊥ = 20, k∥ = 50, and v = [1, 0, 0]
K = 3x3
    50     0     0
     0    20     0
     0     0    20

Tensor when k⊥ = 20, k∥ = 50, and v = [0.57735, 0.57735, 0.57735]
K = 3x3
   30.0000   10.0000   10.0000
   10.0000   30.0000   10.0000
   10.0000   10.0000   30.0000

Tensor when k⊥ = 25, k∥ = 45, and v = [1, 0, 0]
K = 3x3
    45     0     0
     0    25     0
     0     0    25

Tensor when k⊥ = 25, k∥ = 45, and v = [0.57735, 0.57735, 0.57735]
K = 3x3
   31.6667    6.6667    6.6667
    6.6667   31.6667    6.6667
    6.6667    6.6667   31.6667

Tensor when k⊥ = 30, k∥ = 40, and v = [1, 0, 0]
K = 3x3
    40     0     0
     0    30     0
     0     0    30

Tensor when k⊥ = 30, k∥ = 40, and v = [0.57735, 0.57735, 0.57735]
K = 3x3
   33.3333    3.3333    3.3333
    3.3333   33.3333    3.3333
    3.3333    3.3333   33.3333

This example shows how uniaxial anisotropy can be efficiently represented across both temperature variations and orientation differences, yielding a complete set of tensors for multi-grain, multi-temperature analyses.

See Also