Skip to content

feature: combine multiple assimilation methods #219

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

Draft
wants to merge 45 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a4cd977
combine multiple assimilation methods
LinhWuerzburger Nov 30, 2022
9febdc6
remove class_name of assimilation method
LinhWuerzburger Nov 30, 2022
b12de29
replaced the necessary field changes with an optional class field cha…
LinhWuerzburger Nov 30, 2022
24060f3
correction gtest
LinhWuerzburger Nov 30, 2022
f4f159a
add random field test
LinhW Dec 1, 2022
6800cde
add deleted obstacle to test
LinhW Dec 1, 2022
1fcab80
save names of deleted objects
LinhW Dec 1, 2022
4cd8159
python: add attributes cells and index to obstacle
LinhW Dec 1, 2022
7a9746d
python: construction of deleted object doesn't need details
LinhW Dec 1, 2022
93e221c
python: index and cells are part of obstacles
LinhW Dec 1, 2022
3829d2e
python: added open door to steckler scenario
LinhW Dec 1, 2022
514d9e5
correction of deleted objects. now in parameter reader as vector
LinhWuerzburger Dec 1, 2022
172f280
obstacles are only added once
LinhWuerzburger Dec 1, 2022
32f348f
correction of gtest. comparison of two doubles through difference
LinhWuerzburger Dec 1, 2022
0a38b78
correction of gtest. comparison of two doubles through difference
LinhWuerzburger Dec 1, 2022
10a16e8
python: set all fields to zero when adding a new obstacle
LinhWuerzburger Dec 6, 2022
6130261
deleting unnecessary attributes
LinhWuerzburger Dec 8, 2022
5a2cbfc
fix: removed left over override
LinhWuerzburger Dec 8, 2022
565d1e2
.vis is now a parameter
LinhWuerzburger Dec 14, 2022
47bd530
python: add state to output info
LinhW Dec 14, 2022
aa5a314
python: replace rooms with obstacles - not working yet
LinhW Dec 14, 2022
a4598b9
python: correction of wrong file name for fields
LinhW Dec 14, 2022
89041bf
python: correction
Dec 19, 2022
d729477
python: add full corridor case
LinhW Dec 19, 2022
477c032
python: correction of replacing obstacle room with walls
LinhWuerzburger Dec 19, 2022
0bc537c
python: fix: check if dictionary is empty
Dec 24, 2022
91ecc39
python: fix: reset n after loop
Dec 24, 2022
4d1364a
small corrections
LinhWuerzburger Jan 3, 2023
2b1f4d4
python: measure times
LinhWuerzburger Jan 5, 2023
dae0a09
python: removed one time gradient
LinhWuerzburger Jan 5, 2023
ee6abe4
python: correction of waiting behaviour
LinhWuerzburger Jan 5, 2023
67f0f0b
fix: write out interval working even if float inaccuracy makes the nu…
LinhWuerzburger Jan 7, 2023
a5ee01d
update map function
LinhWuerzburger Jan 13, 2023
7a914c2
added nelder-mead
LinhWuerzburger Jan 15, 2023
8c8a575
fix: dimension of heat source
LinhWuerzburger Jan 15, 2023
51c2105
python: separate functions
LinhW Jan 16, 2023
7449cae
python: optimise downhill simplex method
LinhWuerzburger Jan 23, 2023
6faea3c
relative delta for HRR
LinhWuerzburger Jan 23, 2023
0de187a
python: update
LinhWuerzburger Jan 25, 2023
ace62e5
python: fix: lowercase only for comparison
LinhWuerzburger Jan 25, 2023
b19341c
python: added pretty print for sensor dictionary
LinhWuerzburger Jan 25, 2023
a5ecb93
added z0 as parameter
LinhWuerzburger Jan 28, 2023
fb0a802
python: wip: start simulation with correct offset
LinhWuerzburger Jan 28, 2023
8f9bce9
python: fix: projected time and sensor time
LinhWuerzburger Jan 28, 2023
67b532a
python: added log messages
LinhWuerzburger Jan 28, 2023
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
134 changes: 96 additions & 38 deletions data_assimilation/ARTSS.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,61 @@
#!/usr/bin/env python3
import os
import xml.etree.ElementTree as ET
from typing import List, Dict, Union, Set
from typing import List, Dict, Union, Set, TextIO

import numpy as np

from obstacle import Obstacle, PATCHES, STATE
from utility import log


def start_new_instance(output_file: str, directory: str, artss_exe_path: str,
artss_exe: str = 'artss_data_assimilation_serial'):
cwd = os.getcwd()
os.chdir(directory)
exe_command = f'mpirun --np 2 {os.path.join(artss_exe_path, artss_exe)} {output_file}'
print(os.getcwd(), exe_command)
os.system(exe_command)
os.chdir(cwd)


def change_xml(change: Dict[str, float], input_file: str, output_file: str, artss_root_path: str, artss_data_path: str, file_debug: TextIO):
out_file = os.path.join(artss_data_path, output_file)
log(f'out_file: {out_file}', file_debug)

command = ''
for key in change:
command += f' --{key} {change[key]}'
command = f'{os.path.join(artss_root_path, "tools", "change_xml.sh")} -i {input_file} -o {out_file} --loglevel off' + command
log(f'{command}', file_debug)
os.system(command)


def create_start_xml(change: dict, input_file: str, output_file: str, t_revert: float, file: str, t_end: float,
directory: str, artss_path: str, file_debug: TextIO, dir_name: str = '') -> [str, str]:
f = os.path.join('..', file)
f = f.replace("/", "\/")

command = ''
name = ''
for key in change:
command += f' --{key} {change[key]}'
name += f'{key}_'
name = name[:-1]

if not dir_name == '':
name = dir_name
output_dir = os.path.join(directory, '.vis', name)
if not os.path.exists(output_dir):
os.makedirs(output_dir)

out_file = os.path.join(output_dir, output_file)
log(f'out_file: {out_file}', file_debug)
log(f'out_dir: {output_dir}', file_debug)
command = f'{os.path.join(artss_path, "tools", "change_xml.sh")} -i {input_file} -o {out_file} --da {t_revert} "{f}" 7779 --tend {t_end} --loglevel off' + command
log(f'{command}', file_debug)
os.system(command)
return out_file, output_dir


class XML:
Expand Down Expand Up @@ -52,7 +102,7 @@ def get_output_time_step(self) -> float:
return 1

def get_temperature_source(self) -> dict:
if self.temperature_source is None:
if not self.temperature_source:
# check if temperature source is even there ? or crash
root = self.xml_tree.getroot()
source_tree = root.find('solver').find('temperature').find('source')
Expand Down Expand Up @@ -89,8 +139,7 @@ def __init__(self, domain_param: Dict[str, float], enable_computational_domain:
for o in obstacles:
self.obstacles[o.name] = o
self.domain_boundary_cells: Dict[str, Set[int]] = {}
self.domain_inner_cells: Dict[str, Set[int]] = {}
self.obstacle_cells: Dict[str, Dict[str, Set[int]]] = {}
self.domain_inner_cells: Set[int] = set()
self.computational_domain(domain_param, enable_computational_domain)
self.calculate_domain()
self.calculate_indices()
Expand Down Expand Up @@ -166,12 +215,12 @@ def calculate_obstacle_cells(self, o: Obstacle):
index_y2: int = self.get_matching_obstacle_index(o.geometry['oy2'], 'y')
index_z1: int = self.get_matching_obstacle_index(o.geometry['oz1'], 'z') + 1
index_z2: int = self.get_matching_obstacle_index(o.geometry['oz2'], 'z')
o.index = {'x1': index_x1, 'x2': index_x2, 'y1': index_y1, 'y2': index_y2, 'z1': index_z1, 'z2': index_z2}
for i in range(index_x1 + 1, index_x2):
for j in range(index_y1 + 1, index_y2):
for k in range(index_z1 + 1, index_z2):
inner_cells.append(self.calculate_index(i, j, k))
self.obstacle_cells[o.name]: Dict[str, Set[int]] = {}
self.obstacle_cells[o.name]['inner cells'] = set(inner_cells)
self.obstacles[o.name].cells['inner cells'] = set(inner_cells)

# indices of obstacle boundary cells
front = []
Expand All @@ -180,26 +229,26 @@ def calculate_obstacle_cells(self, o: Obstacle):
for j in range(index_y1, index_y2 + 1):
front.append(self.calculate_index(i, j, index_z1))
back.append(self.calculate_index(i, j, index_z2))
self.obstacle_cells[o.name]['front'] = set(front)
self.obstacle_cells[o.name]['back'] = set(back)
self.obstacles[o.name].cells['front'] = set(front)
self.obstacles[o.name].cells['back'] = set(back)

bottom = []
top = []
for i in range(index_x1, index_x2 + 1):
for k in range(index_z1, index_z2 + 1):
bottom.append(self.calculate_index(i, index_y1, k))
top.append(self.calculate_index(i, index_y2, k))
self.obstacle_cells[o.name]['bottom'] = set(bottom)
self.obstacle_cells[o.name]['top'] = set(top)
self.obstacles[o.name].cells['bottom'] = set(bottom)
self.obstacles[o.name].cells['top'] = set(top)

left = []
right = []
for j in range(index_y1, index_y2 + 1):
for k in range(index_z1, index_z2 + 1):
left.append(self.calculate_index(index_x1, j, k))
right.append(self.calculate_index(index_x2, j, k))
self.obstacle_cells[o.name]['left'] = set(left)
self.obstacle_cells[o.name]['right'] = set(right)
self.obstacles[o.name].cells['left'] = set(left)
self.obstacles[o.name].cells['right'] = set(right)

def calculate_domain_boundaries(self):
front = []
Expand Down Expand Up @@ -236,9 +285,9 @@ def calculate_domain_inner(self):
for k in range(self.domain_param['start z index CD'], self.domain_param['end z index CD']):
inner.append(self.calculate_index(i, j, k))
inner = set(inner)
for oc in self.obstacle_cells:
for type_of_cell in self.obstacle_cells[oc]:
inner = inner - self.obstacle_cells[oc][type_of_cell]
for obstacle in self.obstacles.values():
for type_of_cell in obstacle.cells:
inner = inner - obstacle.cells[type_of_cell]
self.domain_inner_cells = inner

def calculate_index(self, i, j, k):
Expand All @@ -250,14 +299,14 @@ def print_info(self):
f"Domain size inner cells: {self.domain_param['nx']} {self.domain_param['ny']} {self.domain_param['nz']}\n"
f"step size (x|y|z): ({self.domain_param['dx']}|{self.domain_param['dy']}|{self.domain_param['dz']})")
for o in self.obstacles.values():
print(f"-- Obstacle {o.name}\n"
print(f"-- Obstacle {o.name} ({o.state})\n"
f" size of slices (Front|Back Bottom|Top Left|Right): "
f"{len(self.obstacle_cells[o.name]['front'])}|"
f"{len(self.obstacle_cells[o.name]['back'])} "
f"{len(self.obstacle_cells[o.name]['bottom'])}|"
f"{len(self.obstacle_cells[o.name]['top'])} "
f"{len(self.obstacle_cells[o.name]['left'])}|"
f"{len(self.obstacle_cells[o.name]['right'])}\n"
f"{len(self.obstacles[o.name].cells['front'])}|"
f"{len(self.obstacles[o.name].cells['back'])} "
f"{len(self.obstacles[o.name].cells['bottom'])}|"
f"{len(self.obstacles[o.name].cells['top'])} "
f"{len(self.obstacles[o.name].cells['left'])}|"
f"{len(self.obstacles[o.name].cells['right'])}\n"
f" coords (x y z): "
f"({o.geometry['ox1']}|{o.geometry['ox2']}) "
f"({o.geometry['oy1']}|{o.geometry['oy2']}) "
Expand All @@ -279,23 +328,27 @@ def print_debug(self):
print(f"index X PD: ({self.domain_param['start x index PD']}|{self.domain_param['end x index PD']}) "
f"index Y PD: ({self.domain_param['start y index PD']}|{self.domain_param['end y index PD']}) "
f"index Z PD: ({self.domain_param['start z index PD']}|{self.domain_param['end z index PD']})")
print(f"inner cells index: ({min(self.domain_inner_cells)}|{max(self.domain_inner_cells)})")
for patch in PATCHES:
print(f"boundary cells index {patch}: ({min(self.domain_boundary_cells[patch])}|{max(self.domain_boundary_cells[patch])})")
print()
for o in self.obstacles.values():
print(f"-- Obstacle {o.name}\n"
f" size of slices (Front|Back Bottom|Top Left|Right): "
f"{len(self.obstacle_cells[o.name]['front'])}|"
f"{len(self.obstacle_cells[o.name]['back'])} "
f"{len(self.obstacle_cells[o.name]['bottom'])}|"
f"{len(self.obstacle_cells[o.name]['top'])} "
f"{len(self.obstacle_cells[o.name]['left'])}|"
f"{len(self.obstacle_cells[o.name]['right'])}\n"
f"{len(self.obstacles[o.name].cells['front'])}|"
f"{len(self.obstacles[o.name].cells['back'])} "
f"{len(self.obstacles[o.name].cells['bottom'])}|"
f"{len(self.obstacles[o.name].cells['top'])} "
f"{len(self.obstacles[o.name].cells['left'])}|"
f"{len(self.obstacles[o.name].cells['right'])}\n"
f" coords (x y z): "
f"({o.geometry['ox1']}|{o.geometry['ox2']}) "
f"({o.geometry['oy1']}|{o.geometry['oy2']}) "
f"({o.geometry['oz1']}|{o.geometry['oz2']})")
str_obstacle_cells = ''
for patch in PATCHES:
start = min(self.obstacle_cells[o.name][patch])
end = max(self.obstacle_cells[o.name][patch])
start = min(self.obstacles[o.name].cells[patch])
end = max(self.obstacles[o.name].cells[patch])
str_obstacle_cells += f" ({patch}: {start}|{end})\n"
k = self.get_k(start)
j = self.get_j(start, k=k)
Expand All @@ -305,7 +358,7 @@ def print_debug(self):
j = self.get_j(end, k=k)
i = self.get_i(end, k=k, j=j)
str_obstacle_cells += f" {patch} end: {i}|{j}|{k}\n"
print(str_obstacle_cells)
print(str_obstacle_cells[:-2])

def get_ijk_from_xyz(self, coord_x, coord_y, coord_z):
return self.get_i_from_x(coord_x), self.get_j_from_y(coord_y), self.get_k_from_z(coord_z)
Expand Down Expand Up @@ -336,11 +389,11 @@ def get_type(self, index):
for p in PATCHES.keys():
if index in self.domain_boundary_cells[p]:
matches.append(f'domain boundary cell ({p})')
for oc in self.obstacle_cells:
for oc in self.obstacles:
for p in PATCHES.keys():
if index in self.obstacle_cells[oc][p]:
if index in self.obstacles[oc].cells[p]:
matches.append(f'obstacle boundary cell ({oc}/{p})')
if index in self.obstacle_cells['inner cells']:
if index in self.obstacles[oc].cells['inner cells']:
matches.append(f'obstacle inner cell ({oc})')
if len(matches) == 0:
return "cell type unknown"
Expand All @@ -356,17 +409,22 @@ def change_obstacle(self, obstacle: Obstacle):
self.obstacles[obstacle.name] = obstacle
self.calculate_obstacle_cells(obstacle)

def remove_obstacle(self, name: str):
self.obstacles[name].state = 'deleted'
def remove_obstacle(self, name: str) -> Obstacle:
obstacle = self.obstacles.pop(name)
obstacle.state = 'deleted'
return obstacle

def set_value_of_obstacle_cells(self, value: float, field: np.ndarray, obstacle_name: str):
cells: Set[float] = set()
for val in self.obstacle_cells[obstacle_name].values():
for val in self.obstacles[obstacle_name].cells.values():
cells.update(val)

for cell in cells:
field[cell] = value

def set_value_of_obstacle_patch(self, value: float, field: np.ndarray, obstacle_name: str, patch: str):
for cell in self.obstacle_cells[obstacle_name][patch]:
for cell in self.obstacles[obstacle_name].cells[patch]:
field[cell] = value

def get_obstacles(self):
return list(self.obstacles.values())
8 changes: 6 additions & 2 deletions data_assimilation/TCP_client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import datetime
import socket
import struct


class TCPClient:
def __init__(self):
# Create a TCP/IP socket
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

timeval = struct.pack('ll', 20, 0)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeval)
# Connect the socket to the port where the server is listening
self.server_address = ('localhost', 7777)

Expand All @@ -23,7 +26,8 @@ def send_message(self, message: bin):
# Look for the response
expected_response = "message was received: Rollback done"
response = ''

self.socket.settimeout(30)
print('time', datetime.datetime.now())
while len(response) < len(expected_response):
try:
reply = self.socket.recv(16)
Expand Down
Loading