Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add heat transfer #108

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
351159c
Add heat transfer
streeve Jun 18, 2024
325798a
fixup: solver comments
streeve Jul 3, 2024
43bf7da
Add new heat transfer example
streeve Jul 31, 2024
de4a86a
Initialize particle temperature as temp0
pabloseleson Aug 1, 2024
e2fb205
fixup: ghosted BC particles
streeve Aug 1, 2024
17601d3
Fix heat transfer solver to use reference bond length
pabloseleson Aug 6, 2024
7631943
Rearrange order of operations in solver for heat transfer
pabloseleson Aug 6, 2024
e5519b8
Modified thermal deformation with heat transfer to test various b.c. …
pabloseleson Aug 8, 2024
cabce6c
fixup: heat transfer profiles
streeve Aug 8, 2024
38ea025
fixup: unused
streeve Aug 8, 2024
c3d352b
Renamed thermal_expansion_coeff in json file
pabloseleson Aug 9, 2024
be854ef
fixup: review clarifications
streeve Aug 19, 2024
e478e6a
fixup: boundaries after region update
streeve Aug 19, 2024
b9235f9
fixup: only enable elastic heat transfer for now
streeve Aug 19, 2024
a53e8bc
fixup: rename temperature conduction terms
streeve Aug 20, 2024
5db7fef
readme: update features
streeve Aug 20, 2024
0d95b79
Added example on a cube geometry
pabloseleson Aug 22, 2024
bd8e279
Added modified example and temperature output capability
pabloseleson Sep 4, 2024
ebdfdd0
Fixed heat transer solver and add temporary example
pabloseleson Sep 5, 2024
8c1ef36
Modified b.c. on thermal deformation heat transfer example
pabloseleson Sep 10, 2024
543c22c
Changed example output profile dimension
pabloseleson Sep 10, 2024
37e422f
Subcycle thermal step
streeve Sep 9, 2024
ffdbe3b
clean up heat transfer example
streeve Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ CabanaPD currently includes the following:
- Elastic (no failure)
- Brittle fracture
- Thermomechanics (bond-based only)
- Optional heat transfer (elastic only)
- Time integration
- Velocity Verlet
- Pre-crack creation
Expand Down
5 changes: 4 additions & 1 deletion examples/thermomechanics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ target_link_libraries(ThermalDeformation LINK_PUBLIC CabanaPD)
add_executable(ThermalCrack thermal_crack.cpp)
target_link_libraries(ThermalCrack LINK_PUBLIC CabanaPD)

install(TARGETS ThermalDeformation ThermalCrack DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable(ThermalDeformationHeatTransfer thermal_deformation_heat_transfer.cpp)
target_link_libraries(ThermalDeformationHeatTransfer LINK_PUBLIC CabanaPD)

install(TARGETS ThermalDeformation ThermalCrack ThermalDeformationHeatTransfer DESTINATION ${CMAKE_INSTALL_BINDIR})
24 changes: 13 additions & 11 deletions examples/thermomechanics/inputs/thermal_deformation.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{
"num_cells" : {"value": [100, 30, 3]},
"system_size" : {"value": [1.0, 0.3, 0.03], "unit": "m"},
"density" : {"value": 3980, "unit": "kg/m^3"},
"elastic_modulus" : {"value": 370e+9, "unit": "Pa"},
"thermal_coefficient" : {"value": 7.5E-6, "unit": "oC^{-1}"},
"reference_temperature" : {"value": 20.0, "unit": "oC"},
"horizon" : {"value": 0.03, "unit": "m"},
"final_time" : {"value": 0.01, "unit": "s"},
"timestep" : {"value": 7.5E-7, "unit": "s"},
"output_frequency" : {"value": 100},
"output_reference" : {"value": true}
"num_cells" : {"value": [101, 31, 3]},
"system_size" : {"value": [1.0, 0.3, 0.03], "unit": "m"},
"density" : {"value": 3980, "unit": "kg/m^3"},
"elastic_modulus" : {"value": 370e+9, "unit": "Pa"},
"thermal_expansion_coeff" : {"value": 7.5E-6, "unit": "oC^{-1}"},
"thermal_conductivity" : {"value": 31, "unit": "W/(m.K)"},
"specific_heat_capacity" : {"value": 880, "unit": "J/(kg.K)"},
"reference_temperature" : {"value": 20.0, "unit": "oC"},
"horizon" : {"value": 0.03, "unit": "m"},
"final_time" : {"value": 0.01, "unit": "s"},
"timestep" : {"value": 7.5E-7, "unit": "s"},
"output_frequency" : {"value": 100},
"output_reference" : {"value": true}
}
16 changes: 16 additions & 0 deletions examples/thermomechanics/inputs/thermal_deformation_cube.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"num_cells" : {"value": [40, 40, 40]},
"system_size" : {"value": [0.1, 0.1, 0.1], "unit": "m"},
"density" : {"value": 8915, "unit": "kg/m^3"},
"elastic_modulus" : {"value": 115e+9, "unit": "Pa"},
"thermal_expansion_coeff" : {"value": 17e-6, "unit": "oC^{-1}"},
"thermal_conductivity" : {"value": 387, "unit": "W/(m.K)"},
"specific_heat_capacity" : {"value": 385, "unit": "J/(kg.K)"},
"reference_temperature" : {"value": 100.0, "unit": "oC"},
"horizon" : {"value": 0.0075, "unit": "m"},
"final_time" : {"value": 8, "unit": "s"},
"timestep" : {"value": 5.1e-8, "unit": "s"},
"thermal_subcycle_steps": {"value": 100},
"output_frequency" : {"value": 1},
"output_reference" : {"value": true}
}
15 changes: 15 additions & 0 deletions examples/thermomechanics/inputs/thermal_deformation_cube_temp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"num_cells" : {"value": [101, 101, 101]},
"system_size" : {"value": [0.1, 0.1, 0.1], "unit": "m"},
"density" : {"value": 8915, "unit": "kg/m^3"},
"elastic_modulus" : {"value": 115e+9, "unit": "Pa"},
"thermal_expansion_coeff" : {"value": 17e-6, "unit": "oC^{-1}"},
"thermal_conductivity" : {"value": 387, "unit": "W/(m.K)"},
"specific_heat_capacity" : {"value": 385, "unit": "J/(kg.K)"},
"reference_temperature" : {"value": 100.0, "unit": "oC"},
"horizon" : {"value": 0.003, "unit": "m"},
"final_time" : {"value": 8, "unit": "s"},
"timestep" : {"value": 0.004, "unit": "s"},
"output_frequency" : {"value": 100},
"output_reference" : {"value": true}
}
2 changes: 1 addition & 1 deletion examples/thermomechanics/thermal_deformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void thermalDeformationExample( const std::string filename )
double nu = 0.25;
double K = E / ( 3 * ( 1 - 2 * nu ) );
double delta = inputs["horizon"];
double alpha = inputs["thermal_coefficient"];
double alpha = inputs["thermal_expansion_coeff"];

// Problem parameters
double temp0 = inputs["reference_temperature"];
Expand Down
204 changes: 204 additions & 0 deletions examples/thermomechanics/thermal_deformation_heat_transfer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/****************************************************************************
* Copyright (c) 2022 by Oak Ridge National Laboratory *
* All rights reserved. *
* *
* This file is part of CabanaPD. CabanaPD is distributed under a *
* BSD 3-clause license. For the licensing terms see the LICENSE file in *
* the top-level directory. *
* *
* SPDX-License-Identifier: BSD-3-Clause *
****************************************************************************/

#include <fstream>
#include <iostream>

#include "mpi.h"

#include <Kokkos_Core.hpp>

#include <CabanaPD.hpp>

// Simulate thermally-induced deformation in a rectangular plate.
void thermalDeformationHeatTransferExample( const std::string filename )
{
// ====================================================
// Use default Kokkos spaces
// ====================================================
using exec_space = Kokkos::DefaultExecutionSpace;
using memory_space = typename exec_space::memory_space;

// ====================================================
// Read inputs
// ====================================================
CabanaPD::Inputs inputs( filename );

// ====================================================
// Material and problem parameters
// ====================================================
// Material parameters
double rho0 = inputs["density"];
double E = inputs["elastic_modulus"];
double nu = 0.25;
double K = E / ( 3 * ( 1 - 2 * nu ) );
double delta = inputs["horizon"];
double alpha = inputs["thermal_expansion_coeff"];
double kappa = inputs["thermal_conductivity"];
double cp = inputs["specific_heat_capacity"];

// Problem parameters
double temp0 = inputs["reference_temperature"];

// ====================================================
// Discretization
// ====================================================
// FIXME: set halo width based on delta
std::array<double, 3> low_corner = inputs["low_corner"];
std::array<double, 3> high_corner = inputs["high_corner"];
std::array<int, 3> num_cells = inputs["num_cells"];
int m = std::floor( delta /
( ( high_corner[0] - low_corner[0] ) / num_cells[0] ) );
int halo_width = m + 1; // Just to be safe.

// ====================================================
// Force model type
// ====================================================
using model_type = CabanaPD::PMB;
using thermal_type = CabanaPD::DynamicTemperature;

// ====================================================
// Particle generation
// ====================================================
// Does not set displacements, velocities, etc.
auto particles =
std::make_shared<CabanaPD::Particles<memory_space, model_type,
typename thermal_type::base_type>>(
exec_space(), low_corner, high_corner, num_cells, halo_width );

// ====================================================
// Custom particle initialization
// ====================================================
auto rho = particles->sliceDensity();
auto temp = particles->sliceTemperature();
auto init_functor = KOKKOS_LAMBDA( const int pid )
{
// Density
rho( pid ) = rho0;
// Temperature
temp( pid ) = temp0;
};
particles->updateParticles( exec_space{}, init_functor );

// ====================================================
// Force model
// ====================================================
auto force_model = CabanaPD::createForceModel(
model_type{}, CabanaPD::Elastic{}, *particles, delta, K, kappa, cp,
alpha, temp0 );

// ====================================================
// Create solver
// ====================================================
auto cabana_pd = CabanaPD::createSolverElastic<memory_space>(
inputs, particles, force_model );

// ====================================================
// Boundary condition
// ====================================================
// Temperature profile imposed on top, bottom, left, and right surfaces
double dx = particles->dx[0];
double dy = particles->dx[1];
double dz = particles->dx[2];
using plane_type = CabanaPD::RegionBoundary<CabanaPD::RectangularPrism>;

// Left surface: x-direction
plane_type plane1( low_corner[0] - dx, low_corner[0] + dx, low_corner[1],
high_corner[1], low_corner[2], high_corner[2] );

// Right surface: x-direction
plane_type plane2( high_corner[0] - dx, high_corner[0] + dx, low_corner[1],
high_corner[1], low_corner[2], high_corner[2] );

// Top surface: y-direction
plane_type plane3( low_corner[0], high_corner[0], high_corner[1] - dy,
high_corner[1] + dy, low_corner[2], high_corner[2] );

// Bottom surface: y-direction
plane_type plane4( low_corner[0], high_corner[0], low_corner[1] - dy,
low_corner[1] + dy, low_corner[2], high_corner[2] );

// Front surface: z-direction
plane_type plane5( low_corner[0], high_corner[0], low_corner[1],
high_corner[1], low_corner[2] - dz, low_corner[2] + dz );

// Back surface: z-direction
plane_type plane6( low_corner[0], high_corner[0], low_corner[1],
high_corner[1], high_corner[2] - dz,
high_corner[2] + dz );

std::vector<plane_type> planes = { plane1, plane2, plane3,
plane4, plane5, plane6 };

auto x = particles->sliceReferencePosition();
// Need to reslice to include ghosted particles on the boundary.
temp = particles->sliceTemperature();
const double low_corner_y = low_corner[1];
// This is purposely delayed until after solver init so that ghosted
// particles are correctly taken into account for lambda capture here.
auto temp_bc = KOKKOS_LAMBDA( const int pid, const double )
{
temp( pid ) = 0.0;
};
auto bc = CabanaPD::createBoundaryCondition(
temp_bc, exec_space{}, *particles, planes, false, 1.0 );

// ====================================================
// Simulation run
// ====================================================
cabana_pd->init( bc );
cabana_pd->run( bc );

// ====================================================
// Outputs
// ====================================================

// Output temperature along the y-axis
auto temp_output = particles->sliceTemperature();
auto value = KOKKOS_LAMBDA( const int pid ) { return temp_output( pid ); };

int profile_dim = 1;
std::string file_name = "temperature_yaxis_profile.txt";
createOutputProfile( MPI_COMM_WORLD, num_cells[1], profile_dim, file_name,
*particles, value );

// Output y-displacement along the x-axis
createDisplacementProfile( MPI_COMM_WORLD,
"ydisplacement_xaxis_profile.txt", *particles,
num_cells[0], 0, 1 );

// Output y-displacement along the y-axis
createDisplacementProfile( MPI_COMM_WORLD,
"ydisplacement_yaxis_profile.txt", *particles,
num_cells[1], 1, 1 );

// Output displacement magnitude along the x-axis
createDisplacementMagnitudeProfile(
MPI_COMM_WORLD, "displacement_magnitude_xaxis_profile.txt", *particles,
num_cells[0], 0 );

// Output displacement magnitude along the y-axis
createDisplacementMagnitudeProfile(
MPI_COMM_WORLD, "displacement_magnitude_yaxis_profile.txt", *particles,
num_cells[1], 1 );
}

// Initialize MPI+Kokkos.
int main( int argc, char* argv[] )
{
MPI_Init( &argc, &argv );
Kokkos::initialize( argc, argv );

thermalDeformationHeatTransferExample( argv[1] );

Kokkos::finalize();
MPI_Finalize();
}
40 changes: 40 additions & 0 deletions src/CabanaPD_ForceModels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#ifndef FORCE_MODELS_H
#define FORCE_MODELS_H

#include <CabanaPD_Constants.hpp>
#include <CabanaPD_Types.hpp>

namespace CabanaPD
Expand Down Expand Up @@ -71,6 +72,45 @@ struct BaseTemperatureModel
}
};

// This class stores temperature parameters needed for heat transfer, but not
// the temperature itself (stored instead in the static temperature class
// above).
struct BaseDynamicTemperatureModel
{
double delta;

double thermal_coeff;
double kappa;
double cp;
bool constant_conductivity;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this refers to the "micro-conductivity"? Perhaps call it "constant_microconductivity"?


BaseDynamicTemperatureModel( const double _delta, const double _kappa,
const double _cp,
const bool _constant_conductivity = true )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we do if we want a different micro-conductivity than the constant one?

{
set_param( _delta, _kappa, _cp, _constant_conductivity );
}

void set_param( const double _delta, const double _kappa, const double _cp,
const bool _constant_conductivity )
{
delta = _delta;
kappa = _kappa;
cp = _cp;
const double d3 = _delta * _delta * _delta;
thermal_coeff = 9.0 / 2.0 * _kappa / pi / d3;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be analogous to Line 52 in CabanaPD_ForceModels_PMB.hpp. I was wondering if we should use a more clear description. There, we used "c". However using "k" may not be good.

constant_conductivity = _constant_conductivity;
}

KOKKOS_INLINE_FUNCTION double conductivity_function( double r ) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the function be called "microconductivity_function"?

{
if ( constant_conductivity )
return thermal_coeff;
else
return 4.0 * thermal_coeff * ( 1.0 - r / delta );
}
};

template <typename ModelType, typename DamageType,
typename ThermalType = TemperatureIndependent, typename... DataTypes>
struct ForceModel;
Expand Down
Loading
Loading