You are currently browsing the category archive for the ‘Programación Orientada a Objetos’ category.

El software Chombo, del Berkeley Lab, combina los métodos en diferencias finitas con las mallas adaptativas (AMR) para resolver, entre otras, PDEs elípticas.

Las siguientes imágenes, en 2D y 3D, se han obtenido a partir de su AMRPoisson:

schSolSouschSol

Anuncios

Finalmente, tenemos ya varias clases abstractas que instanciamos mediante la creación de algunas de sus clases concretas hijas en función de un fichero de configuración.

Algunas de estas clases abstractas son: OdeSolver, SpatialDecomposition, PdeSolver, Kernel, EoS, Equation, Display que pueden ser concretadas en alguna de sus clases herederas (por ejemplo SpatialDecomposition podria ser instanciada como AllPair, como LinkedList o como cualquiera que implementemos posteriormente).

A nivel de código, lo que nos encontramos es lo siguiente:

  1. En el fichero de configuración aparece algo como SpatialDecomposition=LinkedList o <SpatialDecomposition>LinkedList</SpatialDecomposition>, en función del formato que tenga nuestro fichero de configuración
  2. Este fichero lo lee una clase Configuracion que posteriormente es capaz de suministrar esta información.
  3. En algun lugar de nuestro código tenemos SpatialDecomposition *spatialDecomposition y una composición alternativa de acciones donde en una de las ramas, la que se corresponde a la información que nos suministra Configuración, con spatialDecomposition = new LinkedList(...)
  4. En la clase abstracta SpatialDecomposition tenemos un método virtual getNNP que implementan todos sus descendientes, de manera que en LinkedList tenemos su correspondiente implementación para esta clases concreta.
  5. Cuando realizamos la invocación del método spatialDecomposition->getNNP(...) (-> en lugar de . porque tenemos un puntero a la clase y no la clase) este siempre tendrá este formato independientemente de la clase concreta que tengamos en un momento determinado por debajo, por lo que si posteriormente decidimos utilizar AllPair, la llamada anterior queda de la misma manera.

Esto permite que exista una capa de abstracción de manera que el conjunto principal de clases trabaja invocando a métodos virtuales de clases abstractas que se transforman en llamadas a métodos concretos de la clases descendiente instanciada de manera trasparente.

A continuación nuestra primera animación creada con VisIt a partir de ficheros silo generados a partir de llamadas a métodos de nuestras primeras clases.

Temporalmente, aunque es mejor utilizar nuestras partículas simplemente como nodos de interpolación a la hora de visualizar, las mostraremos como puntos.

A partir de este momento, podremos tener una referencia visual de nuestras partículas que nos ayudará mucho a la hora de evaluar como de bien estamos haciendo las cosas.

Sin mas dilación, nuestra minianimación:

No es mas que un conjunto de mil partículas desplazandose sobre un cilindro. La animación consta de 100 ficheros .silo y hemos generado el mpeg con el wizard de VisIt.

Ya dedicamos un post a VisIt. En el creamos una animación a partir de un conjunto de ficheros existentes.

¿Como generamos ficheros .silo desde nuestro código? En primer lugar, necesitamos tener las librerias correspondientes, que las podemos conseguir ejecutando:

./build_visit --console --no-visit --no-thirdparty  --thirdparty-path /usr/local --silo --hdf5 --szip

desde el terminal, y donde build_visit es un fichero que podemos conseguir aqui.

A continuación, necesitamos incluir la libreria <silo.h> en nuestro fichero y añadir:

PLATFORM=i386-apple-darwin10_gcc-4.2

SZIP_DIR=/usr/local/szip/2.1/$(PLATFORM)
SZIP_CPPFLAGS=-I$(SZIP_DIR)/include
SZIP_LDFLAGS=-L$(SZIP_DIR)/lib
SZIP_LIBS=-lsz

HDF5_DIR=/usr/local/hdf5/1.8.4/$(PLATFORM)
HDF5_CPPFLAGS=-I$(HDF5_DIR)/include $(SZIP_CPPFLAGS)
HDF5_LDFLAGS=-L$(HDF5_DIR)/lib $(SZIP_LDFLAGS)
HDF5_LIBS=-lhdf5 $(SZIP_LIBS) -lz

SILO_DIR=/usr/local/silo/4.6.2/$(PLATFORM)
SILO_CPPFLAGS=-I$(SILO_DIR)/include $(HDF5_CPPFLAGS)
SILO_LDFLAGS=-L$(SILO_DIR)/lib $(HDF5_LDFLAGS)
SILO_LIBS=-lsiloh5 $(HDF5_LIBS) -lm

LDFLAGS=$(LDFLAGS) $(SILO_LDFLAGS)
LIBS=$(SILO_LIBS)
CPPFLAGS=$(CPPFLAGS) $(SILO_CPPFLAGS)

a nuestro Makefile

En C++ podemos definir clases abstractas. Son clases pensadas para definir un comportamiento, es decir, un conjunto de métodos sin implementación. Sus clases derivadas están obligadas a implementar estos métodos, siempre i cuando queramos que sean clases concretas instanciables. Los métodos sin implementación de las clases abstractas reciben el nombre de métodos virtuales.

En el siguiente diagrama de clases UML podemos ver dos pequeños ejemplos de como podríamos utilizar las clases abstractas. En el primer caso, tenemos la clase abstracta kernel para implemetar la función kernel del método SPH. Uno de sus métodos debe devolver un valor a partir de los parámetros d y h. La clase kernel define la signatura del método virtual calcular. Las clases derivadas quadraticKernel, cubicKernel y quinticKernel lo implementan de manera diferente. La clase que lo utiliza tiene como atributo un kernel abstracto, de manera que le podremos asignar cualquiera de las derivaciones concretas. Lo mismo ocurre con la clase abstracta Eos que tiene un método que devuelve la presión. Tenemos dos clases derivadas que lo implementan, cada cual de una manera. La clase cliente con un atributo Eos podrá instanciar cualquiera de las dos clases derivadas.

El siguiente código, generado automáticamente por Visual Paradigm, muestra como queda implementado el UML2 de kernel i cubicKernel en C++:

kernel.h

namespace example {

 class kernel {

 public:
   virtual double calculate(double d, double h) = 0;

 };

}

cubicKernel.h

namespace example {

  class cubicKernel : example::kernel {

    public:
      double calculate(double d, double h);

  };

}

cubicKernel.cpp


#include "cubicKernel.h"

double example::cubicKernel::calculate(double d, double h) {

  //aquí va la implementación concreta del kernel cúbico
  throw "Not yet implemented";

}
diciembre 2017
L M X J V S D
« Ago    
 123
45678910
11121314151617
18192021222324
25262728293031