heateq

Métodos para resolver numéricamente la ecuación de calor en dos dimensiones

Implementación en C++

Descripción de la Implementación

Esta implementación simula la difusión de calor en distintas placas de material utilizando el método de diferencias finitas para resolver la ecuación del calor en 2D. Además, aprovecha OpenMP para paralelizar los cálculos y mejorar la eficiencia en sistemas con varios hilos a disposición.

Estructura del Código


Clase Heatmap: Constructores

La clase Heatmap representa una malla 2D para simular la propagación del calor en un material, con miembros que representan las propiedades del sistema como su difusividad térmica. Cada celda de la malla tiene un valor que indica su temperatura en un instante dado. La clase proporciona funcionalidades para:

  • Inicializar la malla con valores específicos.
  • Simular pasos de tiempo utilizando diferencias finitas.
  • Acceder y modificar elementos individuales.
  • Generar representaciones en texto y reportes para análisis posterior.

Heatmap(size_t m, size_t n, double c, double d)

Retorna: Heatmap obj

Este constructor crea una instancia de un sistema a temperatura ambiente en todos sus nodos, para establecer una temperatura distina, utilice el siguiente método:

Ejemplo:

/* Para una placa de hierro (c = 22.8x10^-6 m^s/s) de 40x60 cm,
 * Grilla de 50 x 75 nodos, cada uno de longitud 8x10^-3 m */
Heatmap hierro(50, 75, 22.8e-6, 8e-3);

Heatmap(size_t m, size_t n, double c, double d, double temp)

Retorna: Heatmap obj

Crea una instancia de un objeto Heatmap pero con una temperatura inicial.

Ejemplo:

/* Placa de cobre (c = 113x10^-6) de 40x60 cm, a 10C sobre ambiente */
Heatmap cobre(50, 75, 113e-6, 8e-3, 303.15);

Heatmap(const Heatmap &obj)

Retorna: Heatmap obj

Este constructor de “copia profunda” crea un nuevo objeto utilizando los parámetros el objeto argumento.

Ejemplo:

Heatmap cobre_2 = cobre;

Clase Heatmap: Operaciones

En este caso, la operación que tiene sentido para esta implementación es la de asignación y también la sobrecarga del operador subscript ([]), esto dado a que se utilizan para igualar las condiciones de una grilla a otra o para accesar de manera segura el índice requerido del vector.


operator=(const Heatmap &obj)

Retorna: Heatmap &obj

Operador de asignación que copia los datos de un objeto Heatmap existente al objeto actual.

Ejemplo:

/* ... modificaciones a cobre_2 */
cobre = cobre_2;
/* ... ahora el objeto cobre es cobre_2 */

operator[](size_t i)

Retorna: double

Sobrecarga del operador de acceso que permite obtener un valor de la matriz representada en un vector 1D.

Ejemplo:

std::cout <<
    "Primer elemento de la grilla de cobre: " <<
    cobre[1] <<
    std::endl;

StepFDM(double dt)

Retorna: void

Simula un paso de tiempo dt en la malla utilizando diferencias finitas. Este método está preparado para utilizar varios hilos si se compila con la bandera -fopenmp.

La justificación para realizar este procedimiento es que para calcular los pasos en el tiempo se requieren hacer modificaciones rápidas a una copia del vector, la cual se guarda en el índice correspondiente. Entonces, sin importar el orden de los hilos siempre se va a obtener el mismo resultado. Además, al ser operaciones muy sencillas, dividirlas entre varios hilos mejora el tiempo requerido considerablemente.

Ejemplo:

/* 100 iteraciones de dt = 0.01s,
 * 10s totales de simulación */
for (int i = 1; i <= 100; i++) {
    cobre.StepFDM(0.01);
}

Note que, al requerir el estado anterior para calcular el siguiente, no se puede paralelizar esta parte del bloque, de manera que la forma más conveniente de optimizar el proceso es agilizar lo máximo posible la función StepFDM().


Size()

Retorna: size_t

Retorna el tamaño total de la matriz (número de nodos).

Ejemplo:

std::cout <<
    "Tamaño del vector: " <<
    cobre.Size() <<
    std::endl;

Rows()

Retorna: size_t

Retorna el número de filas de la matriz.

Ejemplo:

std::cout <<
    "Filas de la grilla: " <<
    cobre.Rows() <<
    std::endl;

Cols()

Retorna: size_t

Retorna el número de columntas de la matriz.

Ejemplo:

std::cout <<
    "Columnas de la grilla: " <<
    cobre.Cols() <<
    std::endl;

Map()

Retorna: const std::vector<double>&

Proporciona una referencia constante al vector subyacente que representa la matriz.

Ejemplo:

const std::vector<double> &map = hierro.Map();

Set(size_t i, size_t j, double value)

Retorna: void

Establece un valor de temperatura en una celda específica (i, j).

Ejemplo:

/* Punto caliente de 4x4 nodos en el medio de una placa de hierro */
for (size_t i = hierro.Rows() / 2 - 4; i < hierro.Rows() / 2 + 4; i++) {
	for (size_t j = hierro.Cols() / 2 - 4;
	     j < hierro.Cols() / 2 + 4; j++) {
		hierro.Set(i, j, 393.15);
	}
}

Display()

Retorna: std::string

Genera una representación textual de la matriz en formato humanamente legible.

Ejemplo:

hierro.Display;

Report()

Retorna: std::string

Genera un informe detallado con los parámetros de la simulación y los valores actuales de la matriz, separado por comas por conveniencia.

Ejemplo:

/* Estado después de 4s */
for (int i = 1; i <= 400; i++) {
	cobre.StepFDM(0.01);
	time += dt;
	std::cout << time << "," << cobre.Report() << std::endl;
}
/* Este resultado se podría utilizar para graficar el comportamiento con el
 * software a convenir. */

Avg()

Retorna: double

Calcula el promedio de los valores de la matriz.

Ejemplo:

std::cout << cobre.Avg() << std::endl;