File size: 3,426 Bytes
01a8278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from __future__ import annotations

import importlib.util
import os
import sys
from pathlib import Path
from typing import Dict, List

import numpy as np


def _default_data_generation_dir() -> Path:
    env = os.environ.get("MG_QUARTER_DATA_GEN_DIR")
    if env:
        return Path(env).resolve()
    return (Path(__file__).resolve().parent.parent / "assets" / "quarter_sim").resolve()


def _import_module_from_path(module_name: str, path: Path):
    spec = importlib.util.spec_from_file_location(module_name, path)
    module = importlib.util.module_from_spec(spec)
    assert spec and spec.loader
    spec.loader.exec_module(module)
    return module


def format_vol_fraction(vf: float) -> str:
    return f"{float(vf):.4f}"


def simulate_instances(
    *,
    curve_dir: str,
    mat_type: str,
    vf: float,
    quarter_angles: List[float],
    instances: List[int],
    num_output_points: int = 20,
) -> Dict[int, Dict[str, Dict[str, np.ndarray]]]:
    data_gen_dir = _default_data_generation_dir()
    if not data_gen_dir.exists():
        raise FileNotFoundError(f"Quarter data-generation directory not found: {data_gen_dir}")

    if str(data_gen_dir) not in sys.path:
        sys.path.insert(0, str(data_gen_dir))

    gen_mod = _import_module_from_path("quarter_gen_v2", data_gen_dir / "generate_data_mp_version_2.py")
    lam2 = _import_module_from_path("quarter_lam2", data_gen_dir / "lam2.py")

    curve_dir_path = Path(curve_dir).resolve()
    if not curve_dir_path.exists():
        raise FileNotFoundError(f"curve_dir does not exist: {curve_dir_path}")

    vf_str = format_vol_fraction(vf)
    prefix = f"{mat_type}_{vf_str}"

    original_curve_dir = lam2.CURVE_DIR
    lam2.CURVE_DIR = curve_dir_path
    try:
        mat = lam2.load_ud_material_from_files(prefix)
    finally:
        lam2.CURVE_DIR = original_curve_dir

    full_angles = list(gen_mod.build_full_from_quarter_angles([float(a) for a in quarter_angles]))

    out: Dict[int, Dict[str, Dict[str, np.ndarray]]] = {}
    for inst in instances:
        sim_modes: Dict[str, Dict[str, np.ndarray]] = {}
        for mode in ("11", "22", "12"):
            try:
                ex, sx, ey, _gxy, ezz, _g23, _g13, e11 = gen_mod.run_simulation_with_mat(prefix, full_angles, mode, mat)
                if len(ex) < 2:
                    continue
                x_out = np.linspace(float(ex[0]), float(ex[-1]), int(num_output_points), dtype=np.float32)
                sx_out = np.interp(x_out, ex, sx / 1e6).astype(np.float32)
                if mode == "11":
                    lateral = np.interp(x_out, ex, ey).astype(np.float32)
                    eps33 = np.interp(x_out, ex, ezz).astype(np.float32)
                elif mode == "22":
                    lateral = np.interp(x_out, ex, e11).astype(np.float32)
                    eps33 = np.interp(x_out, ex, ezz).astype(np.float32)
                else:
                    lateral = None
                    eps33 = None

                sim_modes[mode] = {
                    "strain": x_out,
                    "stress": sx_out,
                    "lateral": lateral,
                    "eps33": eps33,
                }
            except Exception:
                continue
        if sim_modes:
            out[int(inst)] = sim_modes

    if not out:
        raise RuntimeError(f"No simulations succeeded for {mat_type} vf={vf_str} angles={quarter_angles}")
    return out