Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
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
2 changes: 2 additions & 0 deletions .ci/azure/setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ else
conda activate simpeg-test
fi

pip install git+https://github.com/jcapriot/docerator

pip install --no-deps --editable .

echo "Conda Environment:"
Expand Down
19 changes: 16 additions & 3 deletions simpeg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
SimPEG is built off of several base classes that define the
general structure of simulations and inversion operations.


SimPEG Base Class
=================
.. autosummary::
:toctree: generated/
base.BaseSimPEG

Simulations
===========

Expand All @@ -20,9 +27,9 @@
simulation.BaseTimeSimulation
simulation.LinearSimulation
simulation.ExponentialSinusoidSimulation
base.BasePDESimulation
base.BaseElectricalPDESimulation
base.BaseMagneticPDESimulation
base.pde.BasePDESimulation
base.pde.BaseElectricalPDESimulation
base.pde.BaseMagneticPDESimulation

Base Surveys, Sources and Receivers
-----------------------------------
Expand Down Expand Up @@ -133,6 +140,12 @@
inverse_problem.BaseInvProblem
inversion.BaseInversion

Documentation building
======================
.. autosummary::
:toctree: generated
base.doc_inherit.bind_signature_to_function
base.doc_inherit.DoceratorMeta
"""

# import discretize as Mesh
Expand Down
15 changes: 9 additions & 6 deletions simpeg/base/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from .pde_simulation import (
BasePDESimulation,
BaseElectricalPDESimulation,
BaseMagneticPDESimulation,
with_property_mass_matrices,
)
import docerator


class BaseSimPEG(metaclass=docerator.DoceratorMeta):
"""Base class for simpeg classes."""

# Developer note:
# This class is mostly used to identify simpeg classes and enable
# class argument documentation inheritance using the meta class.
51 changes: 50 additions & 1 deletion simpeg/base/pde_simulation.py → simpeg/base/pde.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
from typing import Optional

import numpy as np
import numpy.typing as npt
import scipy.sparse as sp
from discretize.base import BaseMesh
from discretize.utils import Zero, TensorType
from ..utils import validate_type
from ..simulation import BaseSimulation
from .. import props
from ..maps import IdentityMap
from scipy.constants import mu_0


Expand Down Expand Up @@ -413,6 +419,24 @@ def _clear_on_prop_update(self):


class BasePDESimulation(BaseSimulation):
"""Base class for PDE simulation.

This class implements the common methods for the finite volume PDE simulations.

Parameters
----------
mesh : discretize.base.BaseMesh
Mesh on which the forward problem is discretized.
"""

def __init__(self, mesh: BaseMesh, **kwargs):
super().__init__(mesh=mesh, **kwargs)

@BaseSimulation.mesh.setter
def mesh(self, value):
# Overwrite the parent's setter to disallow None
self._mesh = validate_type("mesh", value, BaseMesh, cast=False)

@property
def Vol(self):
return self.Mcc
Expand Down Expand Up @@ -492,16 +516,41 @@ def MeI(self):
@with_property_mass_matrices("sigma")
@with_property_mass_matrices("rho")
class BaseElectricalPDESimulation(BasePDESimulation):
"""A simulation containing the electrical physical properties sigma and rho.

Parameters
----------
%(super.mesh)
sigma, rho : (mesh.n_cells,) array_like, optional
Conductivity and resitivity properties. These are linked to each
other as inverses and at most one can be set.
sigmaMap, rhoMap : simpeg.IdentityMap, optional
Relationship between the `model` and conductivity or resistivity.
These are linked to each other as inverses and at most one can be set.
**kwargs
keyword arguments passed to the parent class.
"""

sigma, sigmaMap, sigmaDeriv = props.Invertible("Electrical conductivity (S/m)")
rho, rhoMap, rhoDeriv = props.Invertible("Electrical resistivity (Ohm m)")
props.Reciprocal(sigma, rho)

def __init__(
self, mesh, sigma=None, sigmaMap=None, rho=None, rhoMap=None, **kwargs
self,
mesh,
sigma: Optional[npt.ArrayLike] = None,
sigmaMap: Optional[IdentityMap] = None,
rho: Optional[npt.ArrayLike] = None,
rhoMap: Optional[IdentityMap] = None,
**kwargs,
):
super().__init__(mesh=mesh, **kwargs)
if sigma and rho:
raise TypeError("Cannot set both sigma and rho.")
self.sigma = sigma
self.rho = rho
if sigmaMap and rhoMap:
raise TypeError("Cannot set both sigmaMap and rhoMap.")
self.sigmaMap = sigmaMap
self.rhoMap = rhoMap

Expand Down
2 changes: 1 addition & 1 deletion simpeg/electromagnetics/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ..survey import BaseSrc
from ..utils import Zero, validate_type
from ..base import BaseElectricalPDESimulation, BaseMagneticPDESimulation
from ..base.pde import BaseElectricalPDESimulation, BaseMagneticPDESimulation

__all__ = ["BaseEMSimulation", "BaseEMSrc"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import scipy.sparse as sp

from .... import maps, props
from ....base import BasePDESimulation
from ....base.pde import BasePDESimulation
from ....data import Data
from ..resistivity import Simulation2DCellCentered as DC_2D_CC
from ..resistivity import Simulation2DNodal as DC_2D_N
Expand Down
143 changes: 86 additions & 57 deletions simpeg/electromagnetics/static/resistivity/simulation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import numpy as np
import scipy.sparse as sp
from typing import Optional
from discretize.base import BaseMesh
from ....typing import IndexArray

from ....utils import (
mkvc,
Expand All @@ -9,7 +12,7 @@
validate_active_indices,
)
from ....data import Data
from ....base import BaseElectricalPDESimulation
from ....base.pde import BaseElectricalPDESimulation
from .survey import Survey
from .fields import Fields3DCellCentered, Fields3DNodal
from .utils import _mini_pole_pole
Expand All @@ -19,22 +22,47 @@
class BaseDCSimulation(BaseElectricalPDESimulation):
"""
Base DC Problem
"""

_mini_survey = None

Ainv = None
Parameters
----------
%(super.mesh)
survey : .resistivity.Survey, optional
The resistivity survey containing all of the electrode sources
and receivers.
bc_type : {"Robin", "Dirichlet", "Neumann"}
Type of boundary condition to use for simulation.
storeJ : bool
Whether to create and store the jacobian matrix. This could require
a large amount of memory, as an array of size (n_data, n_model) is
stored.
miniaturize : bool
Whether to internally represent the `survey` as a potentially smaller
version to speed up computation and reduce the size of the fields object.
surface_faces : (n_bf, ) index_array, optional
Which faces on the mesh to interpret as belonging to the surface. Nuemann
boundary conditions are set on these surfaces. Required for tetrahedral meshes.
**kwargs
keyword arguments passed to the parent class.
"""

def __init__(
self,
mesh,
survey=None,
storeJ=False,
miniaturize=False,
surface_faces=None,
mesh: BaseMesh,
survey: Optional[Survey] = None,
bc_type: Optional[str] = None,
storeJ: bool = False,
miniaturize: bool = False,
surface_faces: Optional[IndexArray] = None,
**kwargs,
):
super().__init__(mesh=mesh, survey=survey, **kwargs)

self._mini_survey = None
if bc_type is not None:
bc_type = "Robin"
self.bc_type = bc_type

self.Ainv = None
self.storeJ = storeJ
self.surface_faces = surface_faces
# Do stuff to simplify the forward and JTvec operation if number of dipole
Expand All @@ -61,6 +89,26 @@ def survey(self, value):
value = validate_type("survey", value, Survey, cast=False)
self._survey = value

@property
def bc_type(self):
"""Type of boundary condition to use for simulation.

Returns
-------
{"Dirichlet", "Neumann", "Robin", "Mixed"}

Notes
-----
Robin and Mixed are equivalent.
"""
return self._bc_type

@bc_type.setter
def bc_type(self, value):
self._bc_type = validate_string(
"bc_type", value, ["Dirichlet", "Neumann", ("Robin", "Mixed")]
)

@property
def storeJ(self):
"""Whether to store the sensitivity matrix
Expand Down Expand Up @@ -314,39 +362,29 @@ def _mini_survey_dataT(self, v):


class Simulation3DCellCentered(BaseDCSimulation):
"""
3D cell centered DC problem
"""3D DC simulation using a cell centered formulation.

Parameters
----------
%(super.mesh)
%(super.survey)
%(super.sigma, super.rho)
%(super.sigmaMap, super.rhoMap)
%(super.model)

Other Parameters
----------------
%(super.*)
"""

_solutionType = "phiSolution"
_formulation = "HJ" # CC potentials means J is on faces
fieldsPair = Fields3DCellCentered

def __init__(self, mesh, survey=None, bc_type="Robin", **kwargs):
def __init__(self, mesh: BaseMesh, survey: Survey = None, **kwargs):
super().__init__(mesh=mesh, survey=survey, **kwargs)
self.bc_type = bc_type
self.setBC()

@property
def bc_type(self):
"""Type of boundary condition to use for simulation.

Returns
-------
{"Dirichlet", "Neumann", "Robin", "Mixed"}

Notes
-----
Robin and Mixed are equivalent.
"""
return self._bc_type

@bc_type.setter
def bc_type(self, value):
self._bc_type = validate_string(
"bc_type", value, ["Dirichlet", "Neumann", ("Robin", "Mixed")]
)

def getA(self, resistivity=None):
"""
Make the A matrix for the cell centered DC resistivity problem
Expand Down Expand Up @@ -476,15 +514,26 @@ def setBC(self):


class Simulation3DNodal(BaseDCSimulation):
"""
3D nodal DC problem
"""3D DC simulation using a nodal formulation.

Parameters
----------
%(super.mesh)
%(super.survey)
%(super.sigma, super.rho)
%(super.sigmaMap, super.rhoMap)
%(super.model)

Other Parameters
----------------
%(super.*)
"""

_solutionType = "phiSolution"
_formulation = "EB" # N potentials means B is on faces
fieldsPair = Fields3DNodal

def __init__(self, mesh, survey=None, bc_type="Robin", **kwargs):
def __init__(self, mesh, survey=None, **kwargs):
super().__init__(mesh=mesh, survey=survey, **kwargs)
# Not sure why I need to do this
# To evaluate mesh.aveE2CC, this is required....
Expand All @@ -495,26 +544,6 @@ def __init__(self, mesh, survey=None, bc_type="Robin", **kwargs):
self.bc_type = bc_type
self.setBC()

@property
def bc_type(self):
"""Type of boundary condition to use for simulation.

Returns
-------
{"Neumann", "Robin", "Mixed"}

Notes
-----
Robin and Mixed are equivalent.
"""
return self._bc_type

@bc_type.setter
def bc_type(self, value):
self._bc_type = validate_string(
"bc_type", value, ["Neumann", ("Robin", "Mixed")]
)

def getA(self, resistivity=None):
"""
Make the A matrix for the cell centered DC resistivity problem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
validate_integer,
validate_active_indices,
)
from ....base import BaseElectricalPDESimulation
from ....base.pde import BaseElectricalPDESimulation
from ....data import Data

from .survey import Survey
Expand Down
Loading