smdogroup / tacs

Finite-element library for analysis and adjoint-based gradient evaluation
Apache License 2.0
102 stars 75 forks source link

Assigning thermal boundary conditions with pyTACS #325

Open sethbunt opened 1 month ago

sethbunt commented 1 month ago

I'm looking into ways to assign a thermal bc with pyTACS in a HeatConduction3D(and eventually LinearThermoelasticity3D) model, but there doesn't seem to be a clear method of doing so. I'm currently attempting to add a heat flux to one face(yellow in image) of a simple 3D box mesh. My first thought was to assign a unique compID to one of the faces, but then I run into issues with having 2D and 3D components. The simulation will run, but the outputs are either zero or nan. I got it to work by using the faceIndex option with the transientProblem.addTractionToComponents function, but there doesn't seem to be a way to find out which faces will get assigned to what index. Please let me know if there is a better method of adding these bcs or if there is a way to find out how faceIndex is assigning faces. box_mesh

timryanb commented 1 month ago

Unfortunately, there's not a convenient way of selecting component faces through TACS/pyTACS in general right now. Since your current problem seems to be geometrically simple my recommendation would be to:

This is definitely a process that we should figure out how to improve upon in the future, thanks for bringing it up

timryanb commented 1 month ago

One alternate solution that came to mind for applying tractions to faces of more complex geometries is using the NASTRAN PLOAD4 card. These cards include information about the traction direction and face that pyTACS can read in automatically using createTACSProbsFromBDF or addLoadFromBDF. The benefit of this approach is that these cards can often be written out from commercial FEM GUI (FEMAP, PATRAN, etc.) which provide easy interfaces for selecting geometric faces and applying the loads .

I don't think we've ever tested this technique on HeatConduction3D elements, but it should still work in principle as long as you set the normal vector (N1,N2,N3) in the PLOAD4 to (1,0,0).

sethbunt commented 1 month ago

Thank you Tim, Took your advice and used the PLOAD4 card to apply the load to the face. This method worked for the HeatConduction3D elements and I got the behavior I was wanting. One odd thing is that the PLOAD4 normal vector needed to be set to (-1,0,0) for it to work correctly. brick_heating

timryanb commented 1 month ago

Thank you Tim, Took your advice and used the PLOAD4 card to apply the load to the face. This method worked for the HeatConduction3D elements and I got the behavior I was wanting. One odd thing is that the PLOAD4 normal vector needed to be set to (-1,0,0) for it to work correctly. brick_heating brick_heating

Glad to hear it worked. The negative normals don't surprise me. the PLOAD4 card has an odd quark of defining positive pressure as acting inward on solid bodies (in the negative normal) rather than outward (positive normal) which is TACS convention.

sethbunt commented 1 month ago

One alternate solution that came to mind for applying tractions to faces of more complex geometries is using the NASTRAN PLOAD4 card. These cards include information about the traction direction and face that pyTACS can read in automatically using createTACSProbsFromBDF or addLoadFromBDF. The benefit of this approach is that these cards can often be written out from commercial FEM GUI (FEMAP, PATRAN, etc.) which provide easy interfaces for selecting geometric faces and applying the loads .

Hi Tim, I'm now trying to change from HeatConduction3D to LinearThermoelasticity3D. So that pload4 method doesn't want to work anymore. Do you know if there is a common way that people apply a heat flux with these new elements? Or if there is a way to get TACS to continue reading the pload4 cards as a heat flux?

timryanb commented 1 month ago

Unfortunately there is no way doing this naturally through a PLOAD4 card since it only supports 3 dimensional force vectors max and TACS LinearThermoelasticity3D require 4. You could hack your way around this for now by going pyTACS source code. If you modify this line in the baseProblem code and hard code it to this:

trac = pressure * np.array([0.0, 0.0, 0.0, -1.0])

Then this should convert your pload magnitude field to a heat load for all LinearThermoelasticity3D elements. This will break the PLOAD4 card for all other elements, so this is really only a temporary hack.

sethbunt commented 1 month ago

Thanks for the help Tim, I tried a modification to the hack that you recommended. Instead of hard coding the array to be [0.0, 0.0, 0.0, -1.0], I just appended my desired heatflux to the end of the trac array and it worked. I also checked and it seems that the pressures are still working as well.