From 409ec8b4c2b7aa9f9e209c53b39f64557402f4e8 Mon Sep 17 00:00:00 2001
From: Paul Brinkmeier <hallo@pbrinkmeier.de>
Date: Fri, 15 Dec 2023 15:12:14 +0100
Subject: [PATCH] Experiment state

---
 experiments/.gitignore                     |  1 +
 experiments/Makefile                       | 15 ++++
 experiments/batch/build-cuda               |  2 +-
 experiments/batch/build-nocuda             |  2 +-
 experiments/batch/cuda                     |  2 +-
 experiments/batch/nocuda                   |  2 +-
 experiments/batch/varied-fillings-nocuda   | 26 ++++++
 experiments/generated/.gitkeep             |  0
 experiments/scripts/gen/varied_fillings.py | 54 ++++++++++++
 experiments/templates/varied-fillings.json | 99 ++++++++++++++++++++++
 10 files changed, 199 insertions(+), 4 deletions(-)
 create mode 100644 experiments/Makefile
 create mode 100644 experiments/batch/varied-fillings-nocuda
 create mode 100644 experiments/generated/.gitkeep
 create mode 100644 experiments/scripts/gen/varied_fillings.py
 create mode 100644 experiments/templates/varied-fillings.json

diff --git a/experiments/.gitignore b/experiments/.gitignore
index 2e80076..244293f 100644
--- a/experiments/.gitignore
+++ b/experiments/.gitignore
@@ -2,3 +2,4 @@ venv
 .ipynb_checkpoints
 logs
 __pycache__
+generated/*
diff --git a/experiments/Makefile b/experiments/Makefile
new file mode 100644
index 0000000..d152c03
--- /dev/null
+++ b/experiments/Makefile
@@ -0,0 +1,15 @@
+VARIED_FILLINGS_IS := $(shell seq -w 0 10 100)
+VARIED_FILLINGS_JOBS := $(addprefix generated/varied-fillings-, $(addsuffix .json, ${VARIED_FILLINGS_IS}))
+
+varied-fillings: ${VARIED_FILLINGS_JOBS}
+
+clean:
+	rm -f generated/*
+
+clean-logs:
+	rm -f logs/*
+
+generated/varied-fillings-%.json: scripts/gen/varied_fillings.py templates/varied-fillings.json
+	python scripts/gen/varied_fillings.py $* > $@
+
+.PHONY: varied-fillings clean clean-logs
diff --git a/experiments/batch/build-cuda b/experiments/batch/build-cuda
index 3b2f6cd..69bc7fe 100644
--- a/experiments/batch/build-cuda
+++ b/experiments/batch/build-cuda
@@ -5,7 +5,7 @@
 #SBATCH --account=hkf6
 #SBATCH --partition=develbooster
 #SBATCH --nodes=1
-#SBATCH --ntasks-per-node=1
+#SBATCH --ntasks=1
 #SBATCH --cpus-per-task=48
 #SBATCH --time=01:00:00
 #SBATCH --output=logs/build-cuda-%j.log
diff --git a/experiments/batch/build-nocuda b/experiments/batch/build-nocuda
index 14158c5..e5d9277 100644
--- a/experiments/batch/build-nocuda
+++ b/experiments/batch/build-nocuda
@@ -5,7 +5,7 @@
 #SBATCH --account=hkf6
 #SBATCH --partition=develbooster
 #SBATCH --nodes=1
-#SBATCH --ntasks-per-node=1
+#SBATCH --ntasks=1
 #SBATCH --cpus-per-task=48
 #SBATCH --time=01:00:00
 #SBATCH --output=logs/build-nocuda-%j.log
diff --git a/experiments/batch/cuda b/experiments/batch/cuda
index f404a30..8dac19e 100644
--- a/experiments/batch/cuda
+++ b/experiments/batch/cuda
@@ -9,7 +9,7 @@
 #SBATCH --nodes=1
 # Number of MPI processes
 # TODO: Change the config and set to this the maximum of 48
-#SBATCH --ntasks-per-node=16
+#SBATCH --ntasks=16
 #SBATCH --cpus-per-task=1
 # For now, we are using a single GPU only
 #SBATCH --gres=gpu:1
diff --git a/experiments/batch/nocuda b/experiments/batch/nocuda
index 0f35e8a..dda8ef8 100644
--- a/experiments/batch/nocuda
+++ b/experiments/batch/nocuda
@@ -9,7 +9,7 @@
 #SBATCH --nodes=1
 # Number of MPI processes
 # TODO: Change the config and set to this the maximum of 48
-#SBATCH --ntasks-per-node=16
+#SBATCH --ntasks=16
 #SBATCH --cpus-per-task=1
 #SBATCH --time=01:00:00
 #SBATCH --output=logs/nocuda-%j.log
diff --git a/experiments/batch/varied-fillings-nocuda b/experiments/batch/varied-fillings-nocuda
new file mode 100644
index 0000000..82632e2
--- /dev/null
+++ b/experiments/batch/varied-fillings-nocuda
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+#SBATCH --job-name=varied-fillings-nocuda
+# Forschergruppe Schug
+#SBATCH --account=hkf6
+# 48 Cores, 512GiB RAM, 4x NVIDIA A100 GPUs
+#SBATCH --partition=booster
+# Right now we're using a single node
+#SBATCH --nodes=1
+#SBATCH --ntasks=48
+#SBATCH --cpus-per-task=1
+#SBATCH --time=02:00:00
+#SBATCH --output=logs/varied-fillings-nocuda-%A-%3a.log
+#SBATCH --error=logs/varied-fillings-nocuda-%A-%3a.log
+#SBATCH --array=0-100:10
+
+IDENT=$(printf "%03d" "${SLURM_ARRAY_TASK_ID}")
+SOURCE_DIR=/p/project/cellsinsilico/paulslustigebude
+OUTPUT_DIR="/p/scratch/cellsinsilico/paul/nastja-out/varied-fillings-nocuda-${IDENT}"
+
+mkdir -p "${OUTPUT_DIR}"
+source "${SOURCE_DIR}/activate-nastja-modules"
+
+srun "${SOURCE_DIR}/nastja/build-nocuda/nastja" \
+  -c "${SOURCE_DIR}/ma/experiments/generated/varied-fillings-${IDENT}.json" \
+  -o "${OUTPUT_DIR}"
diff --git a/experiments/generated/.gitkeep b/experiments/generated/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/experiments/scripts/gen/varied_fillings.py b/experiments/scripts/gen/varied_fillings.py
new file mode 100644
index 0000000..0130516
--- /dev/null
+++ b/experiments/scripts/gen/varied_fillings.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import json
+import sys
+
+from functools import reduce
+from operator import mul
+from pathlib import Path
+
+percent_filled = float(sys.argv[1])
+template_path = Path("templates/varied-fillings.json")
+
+initial_cell_size = 4200
+
+with template_path.open(encoding="utf-8") as template_file:
+    config = json.load(template_file)
+
+dims = [
+    size * count
+    for size, count
+    in zip(config["Geometry"]["blocksize"], config["Geometry"]["blockcount"])
+]
+total_volume = reduce(mul, dims, 1)
+target_volume = total_volume * percent_filled / 100
+n_cells = int(target_volume // initial_cell_size)
+# If n_cells is odd, second type gets one more cell
+n_cells_first_type = n_cells // 2
+n_cells_second_type = n_cells - n_cells_first_type
+edge_length = int(target_volume ** (1 / 3))
+offsets = [
+    (dims[0] - edge_length) // 2,
+    (dims[1] - edge_length) // 2,
+    (dims[2] - edge_length) // 2
+]
+
+print(f"Target volume: {target_volume} ({percent_filled}%, edge length: {edge_length}), # of cells: {n_cells}", file=sys.stderr)
+
+if target_volume > 0:
+    config["Filling"]["cells"].append({
+        "shape": "cube",
+        "pattern": "voronoi",
+        "box": [
+            offsets,
+            [
+                min(offsets[0] + edge_length, dims[0] - 1),
+                min(offsets[1] + edge_length, dims[1] - 1),
+                min(offsets[2] + edge_length, dims[2] - 1)
+            ]
+        ],
+        "count": n_cells,
+        "celltype": [0, 0, n_cells_first_type, n_cells_second_type]
+    })
+
+json.dump(config, sys.stdout, indent=2)
diff --git a/experiments/templates/varied-fillings.json b/experiments/templates/varied-fillings.json
new file mode 100644
index 0000000..698e077
--- /dev/null
+++ b/experiments/templates/varied-fillings.json
@@ -0,0 +1,99 @@
+{
+  "#Testing": {
+    "description": "Cellular Potts Model with dynamic ECM"
+  },
+  "Application": "Cells",
+  "Geometry": {
+    "blocksize": [30, 30, 40],
+    "blockcount": [4, 4, 3]
+  },
+  "Settings": {
+    "timesteps": 500,
+    "randomseed": 42
+  },
+  "Filling": {
+    "cells": [
+      {
+        "_comment": "This is for the dynamic ECM",
+        "shape": "cube",
+        "box": [
+          [0, 0, 0],
+          [119, 119, 119]
+        ],
+        "value": 0,
+        "celltype": 0
+      }
+    ]
+  },
+  "CellsInSilico": {
+    "liquid": 1,
+    "adhesion": {
+      "matrix": [
+        [ 0, 0,  0, 10],
+        [ 0, 0,  0, 10],
+        [10, 0, 40,  5],
+        [10, 0,  5, 40]
+      ]
+    },
+    "temperature": 15,
+    "volume": {
+      "default": {
+        "storage": "const",
+        "value": 5000
+      },
+      "lambda": {
+        "storage": "const",
+        "value": 10
+      }
+    },
+    "surface": {
+      "default": {
+        "storage": "const",
+        "value": 1000
+      },
+      "lambda": {
+        "storage": "const",
+        "value": 10
+      }
+    },
+    "cleaner": {
+      "killdistance": 100
+    },
+    "checkerboard": "00",
+    "energyfunctions": ["Volume00", "Surface00", "Adhesion00", "DynamicECM00"],
+    "centerofmass": {
+      "steps": 10
+    },
+    "dynamicecm": {
+      "enabled": true,
+      "stepsPerMcs": 200,
+      "pushSteps": 10,
+      "pushWeight": 2,
+      "ecmCellID": 0,
+      "deltat": 0.1,
+      "eta": 0.25,
+      "k0": 0.1,
+      "k1": 0.1,
+      "c": 4,
+      "alpha": 2,
+      "d": 0.3,
+      "phi": 1
+    }
+  },
+  "Writers": {
+    "ParallelVTK_Cells": {
+      "writer": "ParallelVtkImage",
+      "outputtype": "UInt32",
+      "field": "cells",
+      "steps": 5
+    },
+    "ParallelVTK_Displacement": {
+      "writer": "ParallelVtkImage",
+      "outputtype": "Float32",
+      "field": "dynamicecm",
+      "components": [0, 1, 2],
+      "steps": 5
+    }
+  },
+  "WriteActions": ["ParallelVTK_Cells", "ParallelVTK_Displacement"]
+}