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

Refactoring adaptivity data handling #135

Merged
merged 6 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## latest

- Refactor large parts of solve and adaptivity to group datasets and simplify handling https://github.com/precice/micro-manager/pull/135
- Add information about adaptivity tuning parameters https://github.com/precice/micro-manager/pull/131
- Put computation of counting active steps inside the adaptivity variant `if` condition https://github.com/precice/micro-manager/pull/130

Expand Down
112 changes: 88 additions & 24 deletions micro_manager/adaptivity/global_adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ def compute_adaptivity(
self,
dt: float,
micro_sims: list,
similarity_dists_nm1: np.ndarray,
is_sim_active_nm1: np.ndarray,
sim_is_associated_to_nm1: np.ndarray,
adaptivity_data_nm1: list,
data_for_adaptivity: dict,
) -> tuple:
"""
Expand All @@ -84,21 +82,21 @@ def compute_adaptivity(
Current time step of the macro-micro coupled problem
micro_sims : list
List of objects of class MicroProblem, which are the micro simulations
similarity_dists_nm1 : numpy array
2D array having similarity distances between each micro simulation pair
is_sim_active_nm1 : numpy array
1D array having state (active or inactive) of each micro simulation on this rank
sim_is_associated_to_nm1 : numpy array
1D array with values of associated simulations of inactive simulations. Active simulations have None
adaptivity_data_nm1 : list
List of numpy arrays:
similarity_dists (2D array having similarity distances between each micro simulation pair)
is_sim_active (1D array having state (active or inactive) of each micro simulation)
sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
data_for_adaptivity : dict
Dictionary with keys as names of data to be used in the similarity calculation, and values as the respective data for the micro simulations

Results
-------
similarity_dists : numpy array
2D array having similarity distances between each micro simulation pair
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation
list
List of numpy arrays:
similarity_dists (2D array having similarity distances between each micro simulation pair)
is_sim_active (1D array having state (active or inactive) of each micro simulation)
sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
"""
for name in data_for_adaptivity.keys():
if name not in self._adaptivity_data_names:
Expand All @@ -115,13 +113,15 @@ def compute_adaptivity(
global_data_for_adaptivity[name] = np.concatenate((data_as_list[:]), axis=0)

similarity_dists = self._get_similarity_dists(
dt, similarity_dists_nm1, global_data_for_adaptivity
dt, adaptivity_data_nm1[0], global_data_for_adaptivity
)

is_sim_active = self._update_active_sims(similarity_dists, is_sim_active_nm1)
is_sim_active = self._update_active_sims(
similarity_dists, adaptivity_data_nm1[1]
)

is_sim_active, sim_is_associated_to = self._update_inactive_sims(
similarity_dists, is_sim_active, sim_is_associated_to_nm1, micro_sims
similarity_dists, is_sim_active, adaptivity_data_nm1[2], micro_sims
)
sim_is_associated_to = self._associate_inactive_to_active(
similarity_dists, is_sim_active, sim_is_associated_to
Expand All @@ -139,12 +139,73 @@ def compute_adaptivity(
)
)

return similarity_dists, is_sim_active, sim_is_associated_to
return [similarity_dists, is_sim_active, sim_is_associated_to]

def get_active_sim_ids(self, is_sim_active: np.array) -> np.ndarray:
"""
Get the ids of active simulations.

Parameters
----------
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation

Returns
-------
numpy array
1D array of active simulation ids
"""
return np.where(is_sim_active[self._global_ids[0] : self._global_ids[-1] + 1])[
0
]

def get_inactive_sim_ids(self, is_sim_active: np.array) -> np.ndarray:
"""
Get the ids of inactive simulations.

Parameters
----------
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation

Returns
-------
numpy array
1D array of inactive simulation ids
"""
return np.where(
is_sim_active[self._global_ids[0] : self._global_ids[-1] + 1] == False
)[0]

def communicate_micro_output(
def get_full_field_micro_output(
self, adaptivity_data: list, micro_output: list
) -> list:
"""
Get the full field micro output from active simulations to inactive simulations.

Parameters
----------
adaptivity_data : list
List of numpy arrays:
similarity_dists (2D array having similarity distances between each micro simulation pair)
is_sim_active (1D array having state (active or inactive) of each micro simulation)
sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
micro_output : list
List of dicts having individual output of each simulation. Only the active simulation outputs are entered.

Returns
-------
micro_output : list
List of dicts having individual output of each simulation. Active and inactive simulation outputs are entered.
"""
micro_sims_output = deepcopy(micro_output)
self._communicate_micro_output(adaptivity_data[1:3], micro_sims_output)

return micro_sims_output

def _communicate_micro_output(
self,
is_sim_active: np.ndarray,
sim_is_associated_to: np.ndarray,
adaptivity_data: list,
micro_output: list,
) -> None:
"""
Expand All @@ -155,13 +216,16 @@ def communicate_micro_output(
----------
micro_sims : list
List of objects of class MicroProblem, which are the micro simulations
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation on this rank
sim_is_associated_to : numpy array
1D array with values of associated simulations of inactive simulations. Active simulations have -2
adaptivity_data : list
List of numpy arrays:
is_sim_active (1D array having state (active or inactive) of each micro simulation)
sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
micro_output : list
List of dicts having individual output of each simulation. Only the active simulation outputs are entered.
"""
is_sim_active = adaptivity_data[0]
sim_is_associated_to = adaptivity_data[1]

inactive_local_ids = np.where(
is_sim_active[self._global_ids[0] : self._global_ids[-1] + 1] == False
)[0]
Expand Down
95 changes: 78 additions & 17 deletions micro_manager/adaptivity/local_adaptivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
each other. A global comparison is not done.
"""
import numpy as np
from copy import deepcopy

from .adaptivity import AdaptivityCalculator

Expand All @@ -26,9 +27,7 @@ def compute_adaptivity(
self,
dt,
micro_sims,
similarity_dists_nm1: np.ndarray,
is_sim_active_nm1: np.ndarray,
sim_is_associated_to_nm1: np.ndarray,
adaptivity_data_nm1: list,
data_for_adaptivity: dict,
) -> tuple:
"""
Expand All @@ -40,22 +39,16 @@ def compute_adaptivity(
Current time step
micro_sims : list
List containing simulation objects
similarity_dists_nm1 : numpy array
2D array having similarity distances between each micro simulation pair.
is_sim_active_nm1 : numpy array
1D array having True if sim is active, False if sim is inactive.
sim_is_associated_to_nm1 : numpy array
1D array with values of associated simulations of inactive simulations. Active simulations have None.
adaptivity_data_nm1 : list
List of numpy arrays: similarity_dists (2D array having similarity distances between each micro simulation pair), is_sim_active (1D array having state (active or inactive) of each micro simulation), sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
data_for_adaptivity : dict
A dictionary containing the names of the data to be used in adaptivity as keys and information on whether
the data are scalar or vector as values.

Returns
-------
similarity_dists : numpy array
2D array having similarity distances between each micro simulation pair.
is_sim_active : numpy array
1D array, True is sim is active, False if sim is inactive.
list
List of numpy arrays: similarity_dists (2D array having similarity distances between each micro simulation pair), is_sim_active (1D array having state (active or inactive) of each micro simulation), sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
"""
for name in data_for_adaptivity.keys():
if name not in self._adaptivity_data_names:
Expand All @@ -66,14 +59,16 @@ def compute_adaptivity(
)

similarity_dists = self._get_similarity_dists(
dt, similarity_dists_nm1, data_for_adaptivity
dt, adaptivity_data_nm1[0], data_for_adaptivity
)

# Operation done globally if global adaptivity is chosen
is_sim_active = self._update_active_sims(similarity_dists, is_sim_active_nm1)
is_sim_active = self._update_active_sims(
similarity_dists, adaptivity_data_nm1[1]
)

is_sim_active, sim_is_associated_to = self._update_inactive_sims(
similarity_dists, is_sim_active, sim_is_associated_to_nm1, micro_sims
similarity_dists, is_sim_active, adaptivity_data_nm1[2], micro_sims
)

sim_is_associated_to = self._associate_inactive_to_active(
Expand All @@ -87,7 +82,73 @@ def compute_adaptivity(
)
)

return similarity_dists, is_sim_active, sim_is_associated_to
return [similarity_dists, is_sim_active, sim_is_associated_to]

def get_active_sim_ids(self, is_sim_active) -> np.ndarray:
"""
Get the ids of active simulations.

Parameters
----------
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation

Returns
-------
numpy array
1D array of active simulation ids
"""
return np.where(is_sim_active)[0]

def get_inactive_sim_ids(self, is_sim_active: np.array) -> np.ndarray:
"""
Get the ids of inactive simulations.

Parameters
----------
is_sim_active : numpy array
1D array having state (active or inactive) of each micro simulation

Returns
-------
numpy array
1D array of inactive simulation ids
"""
return np.where(is_sim_active == False)[0]

def get_full_field_micro_output(
self, adaptivity_data: list, micro_output: list
) -> list:
"""
Get the full field micro output from active simulations to inactive simulations.

Parameters
----------
adaptivity_data : list
List of numpy arrays:
similarity_dists (2D array having similarity distances between each micro simulation pair)
is_sim_active (1D array having state (active or inactive) of each micro simulation)
sim_is_associated_to (1D array with values of associated simulations of inactive simulations. Active simulations have None)
micro_output : list
List of dicts having individual output of each simulation. Only the active simulation outputs are entered.

Returns
-------
micro_output : list
List of dicts having individual output of each simulation. Active and inactive simulation outputs are entered.
"""
micro_sims_output = deepcopy(micro_output)

sim_is_associated_to = adaptivity_data[2]

inactive_sim_ids = self.get_inactive_sim_ids(adaptivity_data[1])

for inactive_id in inactive_sim_ids:
micro_sims_output[inactive_id] = deepcopy(
micro_sims_output[sim_is_associated_to[inactive_id]]
)

return micro_sims_output

def _update_inactive_sims(
self,
Expand Down
Loading
Loading