unit uwin3d;
interface
(*
  5/11/2015
  definición de un espacio 3D para resolución de ecuaciones de dinámica del
  aire para determinación de campos de velocidades en los parques.

  TCaja3D da el soporte para el cálculo.
  Suponemos que la Caja la orientamos en la dirección del viento de forma
  que un observador parado en el origen de coordenadas y mirando hacia en la
  dirección del eje (y) ve "irse" el viento, su brazo extendido apunta en la
  dirección del eje (x) y su cabeza en la dirección del eje (z).

  Las discretizaciones en (x), (y), y (z) pueden ser diferentes.
  Dada las discretizaciones quedan definidos un conjunto de cajitas que
  conforman la discretización del espacio de la Caja. En cada cajita tiene
  que ser posible almacenar un conjunto de magnitides.

  _k = tiempo

  _i = lado de la cajita
  dv = volumen de la cajita
  V_i = velocidad del fluído en la superficie i de la cajita
  N_i = versor Normal del lateral i de la cajita en sentido saliente.

  V = Vector velocidad del aire.
  ro = densidad del aire
  p = presión
  ds_i = área del lateral i de la cajita.


  Balance de masa.
  ================

  ( ro_k+1 - ro_k ) = sum_i ( ro_k * (V_i_k . N_i) * ds_i ) * dt/dv


  Momento.
  ========
  ( V_k+1 - V_k) *ro_k = sum_i(( p_k - p_i_k ) . N_i *ds_i ) * dt/dv



  Densidad del aire
  =====================
   ro = f( HumRel, T, p)  (ecuación empírica conocida)


*)
uses
  Classes, SysUtils, xmatdefs, math, uescala;


type
  TDataRecW3d = record
    vx, vy, vz: NReal; // velocidad del viento.
    ro: NReal; // densidad
    p: NReal; // presion
    T: NReal; // Temperatura
  end;
  PDataRecW3d = ^TDataRecW3d;

  TDAOfDataRecW3d = array of TDataRecW3d; // ( x )

  { TCajaW3d }

  TCajaW3d = class
    escala_x, escala_y, escala_z: TEscala;

      // según el punto de discretización.
    data: TDAOfDataRecW3d;

    // Alturas del piso respecto del fondo de la caja.
    // Con DefAlutra(x, y, z) se fijan puntos y luego se calculan los
    // demás con una iteracción que impone lapaciano nulo.
    z0: TDAOfNReal;
    flg_z0Impuesto: TDAOfBoolean; // tiene TRUE si el punto fue definido fijo
      // false si el punto fue calculdo por iteración.

    // Condiciones de Borde
    vLibre_x, vLibre_y, vLibre_z: NReal; // viento arriba
    TempLibre, TempSuelo: NReal; // Temperatura arriba y abajo

    HumRel: NReal; // Humedad relativa.
    Presion: NREal; // PResion

    constructor Create(largox, largoy, largoz: NReal; nDivx, ndivy, ndivz: integer);

    // funciones auxiliares para indexar dentro de las matrices
    function kOfxy( kx, ky: integer ): integer;
    function kOfxyz( kx, ky, kz: integer ): integer;


    procedure Free;



    // Informa los valores a usar
    procedure DefinirCondicionesDeBorde(
       VLibre_x, Vlibre_y, Vlibre_z: NReal;  // velocidad del viento Libre
       TempLibre, TempSuelo: NReal; // temperatura a nivel del suelo y arriba.
       HumRel: NReal; // humedad relativa.
       Presion: NReal );

    // recorre los bordes de la caja y fija clas condiciones
    procedure FijarCondicionesDeBorde;

    procedure DefAltura( x, y, z: NReal );

  end;


implementation



constructor TCajaW3d.Create( largox, largoy, largoz: NReal;
  nDivx, ndivy, ndivz: integer );
begin
   inherited Create;
   escala_x:= TEscala.Create( -largox/ 2.0,  largox/ 2.0, nDivx );
   escala_y:= TEscala.Create( 0, largoy, nDivy );
   escala_z:= TEscala.Create( 0, largoz, nDivz );
   setlength( data,  nDivx * nDivy * nDivz);
   setlength( z0, (nDivx+1)*(nDivy+1 ) );
   setlength( flg_z0Impuesto, (nDivx+1)*(nDivy+1 ) );
   vclear( z0 );
   vclear( flg_z0Impuesto );
end;

// retorna puntero dentor de data para facilitar acceso
function TCajaW3d.kOfxy( kx, ky: integer ): integer;
begin
   result:= kx + ky * Escala_x.NDivs;
end;


function TCajaW3d.kOfxyz( kx, ky, kz: integer ): integer;
begin
   result:= kx + ( ky + kz* Escala_y.NDivs ) * Escala_x.NDivs;
end;



procedure TCajaW3d.DefinirCondicionesDeBorde(VLibre_x, Vlibre_y,
  Vlibre_z: NReal; TempLibre, TempSuelo: NReal; HumRel: NReal; Presion: NReal); // humedad relativa.
begin
   self.vLibre_x:= vlibre_x;
   self.vlibre_y:= Vlibre_y;
   self.vlibre_z:= vlibre_z;
   self.TempLibre:= TempLibre;
   self.TempSuelo:= TempSuelo;
   self.Presion:= Presion;
   self.HumRel:= HumRel;
end;

procedure TCajaW3d.FijarCondicionesDeBorde;
var
  aRec: TDataRecW3d;
  kREc, kx, ky, kz: integer;
begin
   // piso
   kz:= 0;
   for kx:= 0 to high( Escala_x.puntos ) do
    for ky:= 0 to high( Escala_y.puntos ) do
    begin
      kREc:= kOfxyz( kx, ky, kz );
      aRec:= data[kRec];
      aRec.p:= Presion;
    end;
end;

procedure TCajaW3d.DefAltura(x, y, z: NReal);
begin

end;

procedure TCajaW3d.Free;
begin
end;

end.

