Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geostatistical regularisation implementation #790

Open
louiserr18 opened this issue Nov 26, 2024 · 5 comments
Open

Geostatistical regularisation implementation #790

louiserr18 opened this issue Nov 26, 2024 · 5 comments
Assignees

Comments

@louiserr18
Copy link

Problem description

Dear all,

I am trying to implement geostatistical regularisation into my inversion process. I have had a look at the tutorials and exemples, as well as some of the issues on this forum (eg. #659 Segmentation Fault with custom Constraint Matrix). Depending on what I try, either the kernel (on jupyter lab or spyder) dies and needs restaring during the inversion after printing pyGIMLi - INFO - Set custom constraints matrix; or I think the regularisation is not taken into account.

Your environment

Date: Tue Nov 26 11:19:54 2024 W. Europe Standard Time

            OS : Windows (10 10.0.22631 SP0 Multiprocessor Free)
        CPU(s) : 22
       Machine : AMD64
  Architecture : 64bit
           RAM : 31.5 GiB
   Environment : Jupyter

Python 3.11.10 | packaged by conda-forge | (main, Oct 16 2024, 01:17:14)
[MSC v.1941 64 bit (AMD64)]

       pygimli : 1.5.2
        pgcore : 1.5.0
         numpy : 1.26.4
    matplotlib : 3.9.2
         scipy : 1.14.1
          tqdm : 4.67.0
       IPython : 8.27.0
       pyvista : 0.44.1

Intel(R) oneAPI Math Kernel Library Version 2023.2-Product Build 20230613 for Intel(R) 64 architecture applications

Steps to reproduce

Tell us how to reproduce this issue. Ideally, you could paste the code that produces the error:

import pygimli as pg
from pygimli.physics import ert
import numpy as np
from pygimli.frameworks import PriorModelling
import pygimli.meshtools as mt

# Load data.
data = ert.load('WS_09102024_UNIFIEDBERTFORMAT.txt', verbose=True)
# Add geometric factor.
data['k'] = ert.createGeometricFactors(data, numerical=True)
# Add data error.
data['err'] = ert.estimateError(data, relativeError=0.03, absoluteUError=5e-5)

# OPTION 1: kernel dies.
# Initialise ERTManager.
mgr = ert.ERTManager(sr=False)
mgr.setData(data)
mesh = mgr.createMesh(data=data, paraDX=0.33, paraMaxCellSize=100, paraDepth=50, paraBoundary=5, quality=28)
mgr.setMesh(mesh)
C = pg.matrix.GeostatisticConstraintsMatrix(mesh=mesh, I=[20, 5], dip=-30)
mgr.inv.setRegularization(C=C)

fopmgr = mgr.fop
inv = pg.Inversion(fop= fopmgr)
res = inv.run(data["rhoa"], lam=100000, C=C)

################

# OPTION 2: regularisation not working?

manager = ert.Manager()
final_mesh = manager.createMesh(data=data, paraDX=0.33, paraMaxCellSize=100, paraDepth=50, paraBoundary=5, quality=28)
manager.setData(data)
manager.setMesh(final_mesh)
manager.fop.mesh()

# No geostatistical regularisation
result = manager.invert(
    data=data,
    #mesh=final_mesh,
    lam =1e2,
    #startModel=sM,
    verbose=True
)


C=pg.matrix.GeostatisticConstraintsMatrix(mesh=final_mesh, I=[20, 5], dip=-30)
manager.inv.setRegularization(C=C)
manager.fop.mesh()

# With geostatistical regularisation
result = manager.invert(
    data=data,
    #mesh=final_mesh,
    lam =1e2,
    C = C,
    #startModel=sM,
    verbose=True
)

manager.showResult(elecs = False)

Expected behavior

I would like to implement geostatistical regularisation like in Jordi et al., 2018.

Actual behavior

Either the kernel dies or the regularisation does not work.

WS_09102024_UNIFIEDBERTFORMAT.txt

@halbmy halbmy self-assigned this Nov 26, 2024
@halbmy
Copy link
Contributor

halbmy commented Nov 26, 2024

If you just want to do inversion with geostatistical regularization, you can just use:

mgr.invert(correlationLengths=[20, 5], dip=-30)

Note that for your case 20/5m ranges might be a bit small.

Of course, it should also work with exterior constraint matrix in general. However, the function mgr.createMesh (forwarding to pg.meshtools.createParameterMesh) generates a mesh with a boundary region around the inversion region. The constraint matrix only treats the inversion region, that's why I recommend following the example first doing a normal inversion and then using mgr.paraDomain for creating the C matrix.

@louiserr18
Copy link
Author

louiserr18 commented Nov 27, 2024

Thank you for your quick answer.

When using mgr.invert(correlationLengths=[20, 5], dip=-30), my code fails after this step

pyGIMLi - INFO - Creating GeostatisticConstraintsMatrix for region 2 with: I=[20, 5, 5], dip=-30, strike=0

with the following error message:

Only one global GeostatisticConstraintsMatrixpossible at the moment.

This is not the case when I only specify correlationLengths and not the dip (the code works).

I have included my new (simpler) step sequence.

mgr = ert.ERTManager(sr=False)

mgr.inv.setRegularization(correlationLengths=[20, 5], dip=-30) # I also tried with this line.

mod_before = mgr.invert(data, lam=1000, verbose=True,
                 paraDX=0.33, paraMaxCellSize=100, paraDepth=100, paraBoundary=1, quality=28, correlationLengths=[20, 5], dip=-30)

@louiserr18
Copy link
Author

Would you have an idea as to why this is the case and how I might fix this?

@halbmy
Copy link
Contributor

halbmy commented Dec 13, 2024

I can't really get the problem. For me, this works

data = ert.load("WS_09102024_UNIFIEDBERTFORMAT.txt")
data.estimateError()
mgr = ert.Manager(data)
final_mesh = mgr.createMesh(data=data, paraDX=0.33, paraMaxCellSize=100, paraDepth=50, paraBoundary=5, quality=28)
mgr.setMesh(final_mesh)
mgr.inv.setRegularization(correlationLengths=[200, 50], dip=-30)
mgr.invert(verbose=True)

@louiserr18
Copy link
Author

With this, I still had the message "Critical-Only one global GeostatisticConstraintsMatrixpossible at the moment." It seemed to result from line 633 in the code Frameworks - modelling - class MeshModelling - createConstraints. I also updated PyGIMLi. In the end, I changed the line from pg.critical to pg.info, and it now seems to work fine.

    def createConstraints(self):
        """Create constraint matrix."""
        # just ensure there is valid mesh
        # self.mesh()


        foundGeoStat = False
        for reg, props in self.regionProperties().items():
            if not props['background'] and \
                props['correlationLengths'] is not None or \
                    props['dip'] is not None or props['strike'] is not None:

                cL = props.get('correlationLengths') or 5
                dip = props.get('dip') or 0
                strike = props.get('strike') or 0

                pg.info('Creating GeostatisticConstraintsMatrix for region' +
                        f' {reg} with: I={cL}, dip={dip}, strike={strike}')

                if foundGeoStat is True:
                    pg.info('Only one global GeostatisticConstraintsMatrix'
                                'possible at the moment.') ## Used to be pg.critical. I changed it to pg.info

                # keep a copy of C until refcounting in the core works
                self._C = pg.matrix.GeostatisticConstraintsMatrix(
                    mesh=self.paraDomain, I=cL, dip=dip, strike=strike,
                )

                foundGeoStat = True
                self.setConstraints(self._C)

        if foundGeoStat is False:
            super().createConstraints()

        return self.constraints()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants