Skip to content

Commit

Permalink
Merge branch 'ISSMteam:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
mansakrishna23 authored Jun 25, 2024
2 parents c022799 + c518a69 commit 3a2b420
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 35 deletions.
8 changes: 8 additions & 0 deletions docs/api/pinnicle.physics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ pinnicle.physics.continuity module
:undoc-members:
:show-inheritance:

pinnicle.physics.dummy module
-----------------------------

.. automodule:: pinnicle.physics.dummy
:members:
:undoc-members:
:show-inheritance:

pinnicle.physics.stressbalance module
-------------------------------------

Expand Down
61 changes: 61 additions & 0 deletions docs/examples/advanced.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
Advanced Features in PINNICLE
=============================

PINNICLE is under active development, and several **advanced**/**experimental** features are listed here in alphabetical order:

Additional Loss Functions
-------------------------

It is possible to add additional loss functions to the total loss. Here is an example:

.. code-block:: python
vel_loss = {}
vel_loss['name'] = "vel MAPE"
vel_loss['function'] = "MAPE"
vel_loss['weight'] = 1.0e-6
hp["additional_loss"] = {"vel":vel_loss}
In this example, we define a ``dict`` which contains:
- ``name``: A user-defined name for the loss function.
- ``function``: A function ID from ``LOSS_DICT`` in `deepxde.losses <https://deepxde.readthedocs.io/en/latest/_modules/deepxde/losses.html#get>`_ or `pinnicle.utils.data_misfit <https://pinnicle.readthedocs.io/en/latest/_modules/pinnicle/utils/data_misfit.html#get>`_. These lists include most commonly used loss functions, such as ``"mean"``, ``"MAE"``, ``"MSE"``, ``"MAPE"``, ``"zero"``, ``"VEL_LOG"``, ``"MEAN_SQUARE_LOG"``, etc. Before writing your own loss function, refer to these lists, as these functions are optimized with the backends.
- ``weight``: the weight of this loss function.

Finally, add the new ``dict`` to ``hp["additional_loss"]`` with the key indicating the variable to which this loss function should be applied. In the above example, we are adding the mean absolute percentage error of the velocity magnitude to the total loss.

Dummy Equations
---------------

PINNICLE provides `Dummy <https://pinnicle.readthedocs.io/en/latest/api/pinnicle.physics.html#module-pinnicle.physics.dummy>`_ physics, which allows you to train the neural network using data only. Here is an example:

.. code-block:: python
dummy = {}
dummy["output"] = ['u', 's', 'C']
hp["equations"] = {"DUMMY": dummy}
In this example, we define a ``dict`` with a key ``output``, where the value is a list of three output variables. Then, we add this ``dict`` to ``hp['equations']`` with the key ``DUMMY`` (all uppercase). Additionally, you need to provide the data for ``u``, ``s``, and ``C`` in the ``data`` section, similar to other examples. The neural network will then be trained solely with the provided data.

By default, the ``Dummy`` physics already has ``x`` and ``y`` as ``input``. If there is no need to change this, only the ``output`` needs to be defined.


Architecture of the Neural Network
----------------------------------

PINNICLE supports both fully connected neural networks and parallel neural networks. To choose one, simply set ``hp["is_parallel"]`` to ``False`` or ``True``. Currently, PINNICLE only supports parallel networks for each individual output, and all these networks are of the same size.

Another feature of the neural network architecture is that you can set the number of neurons and layers as follows:

.. code-block:: python
hp["num_neurons"] = 20
hp["num_layers"] = 4
This configuration creates a network with 4 layers, each containing 20 neurons. Alternatively, you can define the number of neurons in each layer using a list:

.. code-block:: python
hp["num_neurons"] = [128, 64, 32, 16]
In this case, the number of layers is inferred from the length of the list, creating a network with 4 layers having 128, 64, 32, and 16 neurons respectively.

File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ User guide
.. toctree::
:maxdepth: 1

pinn_examples
pinnicle_examples


API reference
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ In the future, PINNICLE will support the following backends:

- To install and use the package, you should clone the folder to your local machine and put it along with your project scripts::

$ git clone https://github.com/enigne/PINNICLE.git
$ git clone https://github.com/ISSMteam/PINNICLE.git

* Other dependencies

Expand Down
28 changes: 0 additions & 28 deletions docs/pinn_examples.rst

This file was deleted.

23 changes: 23 additions & 0 deletions docs/pinnicle_examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Examples
========

Here are some examples of solving ice sheet modeling problems using PINNICLE

Basic
-----

.. toctree::
:maxdepth: 1

examples/ssa
.. examples/mc
.. examples/couple
Advanced
--------

.. toctree::
:maxdepth: 2

examples/advanced

Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
"version": "3.9.7"
}
},
"nbformat": 4,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
"version": "3.9.7"
}
},
"nbformat": 4,
Expand Down
7 changes: 5 additions & 2 deletions pinnicle/modeldata/issm_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ def load_data(self):
self.data_dict['s'] = md['geometry']['surface']
self.data_dict['a'] = (md['smb']['mass_balance'] - md['balancethickness']['thickening_rate'])/self.yts
self.data_dict['H'] = md['geometry']['thickness']
try:
# check the friction law
if 'C' in md['friction']:
self.data_dict['C'] = md['friction']['C'] # Weertman
except:
else:
# convert Budd to Weertman type friction coefficient
C_b = md['friction']['coefficient'] # Budd
rho_ice = md['materials']['rho_ice']
rho_w = md['materials']['rho_water']
Expand All @@ -64,6 +66,7 @@ def load_data(self):
N = rho_ice*g*self.data_dict['H'] + rho_w*g*base
N[np.where(N <= 0, True, False)] = 1
self.data_dict['C'] = C_b*np.sqrt(N)

self.data_dict['B'] = md['materials']['rheology_B']
self.data_dict['vel'] = np.sqrt(self.data_dict['u']**2.0+self.data_dict['v']**2.0)
# clean up is any of the keys are empty
Expand Down
19 changes: 18 additions & 1 deletion tests/test_parameters.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
import pinnicle as pinn
from pinnicle.parameter import DataParameter, SingleDataParameter, NNParameter, DomainParameter, PhysicsParameter, Parameters, EquationParameter, TrainingParameter
from pinnicle.physics import SSAEquationParameter
from pinnicle.physics import SSAEquationParameter, DummyEquationParameter

yts = 3600*24*365.0

Expand Down Expand Up @@ -83,6 +83,7 @@ def test_equation_parameters():
p = EquationParameter(SSA)
assert p.input == SSA["input"]
assert p.output == SSA["output"]
assert p.data_weights == SSA["data_weights"]

p = SSAEquationParameter(SSA)
assert p.scalar_variables['n'] == 3.0
Expand Down Expand Up @@ -110,6 +111,22 @@ def test_equation_parameters():
with pytest.raises(Exception):
p = Parameters(hp)

def test_dummy_equation_parameters():
DUMMY = {}
DUMMY["input"] = ["x", "y"]
DUMMY["output"] = ["u", "v", "s", "H", "C"]
DUMMY["output_lb"] = [-1.0e4/yts, -1.0e4/yts, -1.0e3, 10.0, 0.01]
DUMMY["output_ub"] = [ 1.0e4/yts, 1.0e4/yts, 2.5e3, 2.0e3, 1.0e4]

p = DummyEquationParameter(DUMMY)
assert p.input == DUMMY["input"]
assert p.output == DUMMY["output"]
assert p.data_weights == [1.0]*5

DUMMY["data_weights"] = [1.0e-8*yts**2.0, 1.0e-8*yts**2.0, 1.0e-6, 1.0e-6, 1.0e-8]
p = DummyEquationParameter(DUMMY)
assert p.data_weights == DUMMY["data_weights"]

def test_training_parameters():
hp = {}
p = TrainingParameter(hp)
Expand Down

0 comments on commit 3a2b420

Please sign in to comment.