Skip to content
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
89 changes: 89 additions & 0 deletions examples/inverse_problems/mechanics/path-dependent/make_plots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas
import re

actual_prop = 1.0
history_file = "history_pd.csv"

df = pandas.read_csv(history_file)
df.columns = df.columns.str.strip()

print(df)

plt.figure(1)
plt.plot(df["epoch"], df["shear_modulus"], color="blue", label="PINN")
plt.hlines([1.], xmin=0, xmax=np.max(df["epoch"]), color="black", linestyle="--", label="Actual")
plt.legend(loc="best")
plt.xlabel("Epoch")
plt.ylabel("Shear Modulus [MPa]")
plt.savefig(os.path.join(Path(__file__).parent, "property_evolution.png"))

plt.figure(2)
plt.plot(df["epoch"], np.abs(df["shear_modulus"] - actual_prop) / np.abs(actual_prop), color="blue", label="PINN")
plt.hlines([0.01], xmin=0, xmax=np.max(df["epoch"]), color="black", linestyle="--", label="1 Percent Error")
plt.legend(loc="best")
plt.xlabel("Epoch")
plt.xscale("log")
plt.ylabel("Relative Error")
plt.ylim((10e-4, 10e1))
plt.yscale("log")
plt.savefig(os.path.join(Path(__file__).parent, "property_relative_error.png"))


log_file = "pancax.log"
# float_pattern = r'[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?'
float_pattern = r'Array\(([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?), dtype=float64\)'

losses = []
energies = []
field_losses = []
global_losses = []
residuals = []


with open(log_file, "r") as f:
for line in f.readlines():
if "Array" in line:
floats_in_line = re.findall(float_pattern, line)
floats_in_line = list(map(float, floats_in_line))
losses.append(floats_in_line[0])
energies.append(floats_in_line[1])
field_losses.append(floats_in_line[2])
global_losses.append(floats_in_line[3])
residuals.append(floats_in_line[4])


losses = np.array(losses)
energies = np.array(energies)
field_losses = np.array(field_losses)
global_losses = np.array(global_losses)
residuals = np.array(residuals)

print(losses)

# normalize
losses = losses / losses[0]
field_losses = field_losses / field_losses[0]
global_losses = global_losses / global_losses[0]
residuals = residuals / residuals[0]

plt.figure(3)
plt.plot(losses, label="Total Loss")
plt.plot(field_losses, label="Full Field Data Error")
plt.plot(global_losses, label="Global Data Error")
plt.plot(residuals, label="Residual")
plt.legend(loc="best")
plt.xlabel("Epoch")
plt.xscale("log")
plt.ylabel("Normalized Losses")
plt.yscale("log")
plt.savefig(os.path.join(Path(__file__).parent, "losses.png"))

plt.figure(4)
plt.plot(energies)
plt.xlabel("Epoch")
plt.ylabel("Algorithmic Energy")
plt.savefig(os.path.join(Path(__file__).parent, "algorithmic_energy.png"))
12 changes: 7 additions & 5 deletions examples/inverse_problems/mechanics/path-dependent/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
##################
# for reproducibility
##################
key = random.key(10)
key = random.PRNGKey(10)

##################
# file management
Expand Down Expand Up @@ -129,24 +129,26 @@ def loss_function(params, problem, inputs, outputs):
# Training
##################
print(params)
opt_st = opt.init(params)
opt, opt_st = opt.init(params)


# testing stuff
dataloader = FullFieldDataLoader(problem.field_data)

for epoch in range(1000000):
for epoch in range(250000):
for inputs, outputs in dataloader.dataloader(8 * 1024):
params, opt_st, loss = opt.step(params, problem, opt_st, inputs, outputs)
params, opt_st, loss = opt.step(params, opt_st, problem, inputs, outputs)
# params, opt_st, loss = opt.step(params, problem, opt_st, inputs, outputs)
# params, opt_st, loss = opt.step(params, problem, opt_st)


history.write_data("epoch", epoch)
history.write_loss(loss)
history.write_data("shear_modulus", params.physics.constitutive_model.eq_model.shear_modulus)
history.write_data("shear_modulus", params.physics.constitutive_model.eq_model.shear_modulus())

print(epoch)
print(loss)
print(params.physics.constitutive_model.eq_model.shear_modulus())

if epoch % 1000 == 0:
history.to_csv()
6 changes: 4 additions & 2 deletions examples/inverse_problems/mechanics/vanilla/example_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
full_field_data_file = find_data_file('data_full_field.csv')
global_data_file = find_data_file('data_global_data.csv')
mesh_file = find_mesh_file('mesh.g')
logger = Logger('pinn.log', log_every=250)
# logger = Logger('pinn.log', log_every=250)
history = HistoryWriter('history.csv', log_every=250, write_every=250)
pp = PostProcessor(mesh_file)

Expand Down Expand Up @@ -79,7 +79,6 @@
##################
params = Parameters(problem, key)#, seperate_networks=True, network_type=ResNet)
print(params)
# assert False
physics_and_global_loss = EnergyResidualAndReactionLoss(
residual_weight=250.e9, reaction_weight=250.e9
)
Expand Down Expand Up @@ -109,4 +108,7 @@ def loss_function(params, problem, inputs, outputs):
print(epoch)
print(loss)
print(params.physics.constitutive_model)
print(params.physics.constitutive_model.shear_modulus.prop_min)
print(params.physics.constitutive_model.shear_modulus.prop_max)

# print(params.physics.constitutive_model.shear_modulus)
9 changes: 6 additions & 3 deletions pancax/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from pathlib import Path
import argparse
# import jax
import os
import sys


Expand Down Expand Up @@ -61,7 +60,8 @@ def pancax_main():
)
parser.add_argument(
'-l', '--log-file',
default=os.path.join(os.getcwd(), 'pancax.log'),
# default=os.path.join(os.getcwd(), 'pancax.log'),
default=None,
help='Log file for pancax to write stdout and stderr to.'
)
parser.add_argument(
Expand Down Expand Up @@ -104,7 +104,10 @@ def pancax_main():
if not input_file.is_file():
raise FileNotFoundError(f'Input file {input_file} does not exist.')

log_file = Path(args.log_file)
if args.log_file is None:
log_file = args.input_file.split(".py")[0] + ".log"
else:
log_file = args.log_file

# switch over file types, e.g. python or yaml in the future
print(f'Running {input_file}')
Expand Down
4 changes: 2 additions & 2 deletions pancax/constitutive_models/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
# TODO patch up error check in a good way
# probably just make a method to check type on other
class BoundedProperty(eqx.Module):
prop_min: float = eqx.field(static=True)
prop_max: float = eqx.field(static=True)
prop_min: float
prop_max: float
prop_val: Float[Array, "n"]
# TODO
# activation: Callable
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = 'pancax'
version = '0.0.13'
version = '0.0.14'
authors = [
{name = 'Craig M. Hamel, email = <[email protected]>'}
]
Expand Down
Loading