Loop3D / LoopStructural

LoopStructural is an open-source 3D structural geological modelling library.
MIT License
178 stars 35 forks source link

[Question] apply crosscutting relationship to fault network #138

Open GeoMattB opened 1 year ago

GeoMattB commented 1 year ago

I've got multiple generations of faults. abutting relationships work well within the same generation. However I've a couple of later episodes cut the older faults by ~90 degrees and offset them. Is there an option to add this sort of relationship? Also, is there a way to add a little more detail to the intersections to reduce the sawtooth pattern?

image

GeoMattB commented 1 year ago

I think this almost does what I mean. Does this mean that to offset faults with faults I need to make a new fault on the other side of overprinting / cutting fault or is there a way to add segments?

image

lachlangrose commented 1 year ago

Hi Matt,

if you have faults that overprint other faults then what you need to do is pass the keyword faults with an argument which is a list of faults that overprint the fault, so basically if you have three faults a,b, and c and fault c is faulted by both a and b when you build fault c you would use this syntax.

model.create_and_add_fault('c',displacement,faults=[a,b]) where a and b are the object returned from create_and_add_fault or model['a']... hope this helps.

If you do this you will have to have the displacement vector consistent with the direction of displacement and you need to change the displacement magnitude to fit the observed fault pattern.

Cheers

GeoMattB commented 1 year ago

Thanks Lachlan, cool, so this looks like I need to add the youngest fault-set first and then work my way back in time. I know the model doesn't build until we do the update so it's probably not important which order.

Makes sense Matt

GeoMattB commented 1 year ago

model.create_and_add_fault('c',displacement,faults=[a,b]) where a and b are the object returned from create_and_add_fault or model['a']... hope this helps.

If you do this you will have to have the displacement vector consistent with the direction of displacement and you need to change the displacement magnitude to fit the observed fault pattern.

How does loopstructural expect to receive the displacement vector? is it an angle, or dx/dy or something else?

lachlangrose commented 1 year ago

Hi matt,

you need to specify the 3 components of the displacement vector as a list or numpy array. Or use data to constrain the first coordinate of the fault frame. Cheers

GeoMattB commented 1 year ago

Thanks Lachlan, I'm not sure if it's how I'm setting up the faults but if I use a list or array like [1000,1100,250] for displacement or anything except for a single number I get an error. I can't quite figure out how to specify the 3 components.

image

lachlangrose commented 1 year ago

Hi Matt,

Sorry, that is actually my misunderstanding of your question and being in holiday mode!

The fault displacement is defined by a vector which is the slip vector. This vector is then scaled by the displacement which should be a signed value.

If you want to specify the slip vector you'll need to add the argument fault_slip_vector to create_and_add_fault

cheers

GeoMattB commented 1 year ago

To make things "simpler" could I just assume that all older faults are crosscut by all younger faults, even if they aren't anywhere near each other and don't intersect? This way I could just group the younger fault sets rather than specify a crosscutting relationship for each. This might not be a good idea...

GeoMattB commented 1 year ago

This looks a little better. Crosscutting seems to be working but I'm still a little vague on exactly how the movement sense is being entered. the updater complains that theres not enough data to build the Mt William but it's better than it was. image

lachlangrose commented 1 year ago

If you want to visualise the movement sense you can add the following:

view.add_vector_field(BendigoZone_model[fault_display[i]][1],locations=model.regular_grid()[:100])

This will add the slip vector as a vector field randomly within the model at 100 locations (BendigoZone_model.regular_grid() is just a helper method to get points within the model area). The fault restoration vector (opposite to displacement) is this vector multiplied by the displacement magnitude.

GeoMattB commented 1 year ago

Are the displacement and fault_slip_vector I add when I create the fault related to the fault that I'm creating or the younger fault that is doing the displacing? I'm assuming something like this

image