diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json
new file mode 100644
index 00000000..dfa756e1
--- /dev/null
+++ b/dev/.documenter-siteinfo.json
@@ -0,0 +1 @@
+{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2024-11-04T17:32:42","documenter_version":"1.7.0"}}
\ No newline at end of file
diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js
new file mode 100644
index 00000000..82252a11
--- /dev/null
+++ b/dev/assets/documenter.js
@@ -0,0 +1,1064 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) {
+$(document).ready(function() {
+ hljs.highlightAll();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+let timer = 0;
+var isExpanded = true;
+
+$(document).on(
+ "click",
+ ".docstring .docstring-article-toggle-button",
+ function () {
+ let articleToggleTitle = "Expand docstring";
+ const parent = $(this).parent();
+
+ debounce(() => {
+ if (parent.siblings("section").is(":visible")) {
+ parent
+ .find("a.docstring-article-toggle-button")
+ .removeClass("fa-chevron-down")
+ .addClass("fa-chevron-right");
+ } else {
+ parent
+ .find("a.docstring-article-toggle-button")
+ .removeClass("fa-chevron-right")
+ .addClass("fa-chevron-down");
+
+ articleToggleTitle = "Collapse docstring";
+ }
+
+ parent
+ .children(".docstring-article-toggle-button")
+ .prop("title", articleToggleTitle);
+ parent.siblings("section").slideToggle();
+ });
+ }
+);
+
+$(document).on("click", ".docs-article-toggle-button", function (event) {
+ let articleToggleTitle = "Expand docstring";
+ let navArticleToggleTitle = "Expand all docstrings";
+ let animationSpeed = event.noToggleAnimation ? 0 : 400;
+
+ debounce(() => {
+ if (isExpanded) {
+ $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down");
+ $("a.docstring-article-toggle-button")
+ .removeClass("fa-chevron-down")
+ .addClass("fa-chevron-right");
+
+ isExpanded = false;
+
+ $(".docstring section").slideUp(animationSpeed);
+ } else {
+ $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up");
+ $("a.docstring-article-toggle-button")
+ .removeClass("fa-chevron-right")
+ .addClass("fa-chevron-down");
+
+ isExpanded = true;
+ articleToggleTitle = "Collapse docstring";
+ navArticleToggleTitle = "Collapse all docstrings";
+
+ $(".docstring section").slideDown(animationSpeed);
+ }
+
+ $(this).prop("title", navArticleToggleTitle);
+ $(".docstring-article-toggle-button").prop("title", articleToggleTitle);
+ });
+});
+
+function debounce(callback, timeout = 300) {
+ if (Date.now() - timer > timeout) {
+ callback();
+ }
+
+ clearTimeout(timer);
+
+ timer = Date.now();
+}
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require([], function() {
+function addCopyButtonCallbacks() {
+ for (const el of document.getElementsByTagName("pre")) {
+ const button = document.createElement("button");
+ button.classList.add("copy-button", "fa-solid", "fa-copy");
+ button.setAttribute("aria-label", "Copy this code block");
+ button.setAttribute("title", "Copy");
+
+ el.appendChild(button);
+
+ const success = function () {
+ button.classList.add("success", "fa-check");
+ button.classList.remove("fa-copy");
+ };
+
+ const failure = function () {
+ button.classList.add("error", "fa-xmark");
+ button.classList.remove("fa-copy");
+ };
+
+ button.addEventListener("click", function () {
+ copyToClipboard(el.innerText).then(success, failure);
+
+ setTimeout(function () {
+ button.classList.add("fa-copy");
+ button.classList.remove("success", "fa-check", "fa-xmark");
+ }, 5000);
+ });
+ }
+}
+
+function copyToClipboard(text) {
+ // clipboard API is only available in secure contexts
+ if (window.navigator && window.navigator.clipboard) {
+ return window.navigator.clipboard.writeText(text);
+ } else {
+ return new Promise(function (resolve, reject) {
+ try {
+ const el = document.createElement("textarea");
+ el.textContent = text;
+ el.style.position = "fixed";
+ el.style.opacity = 0;
+ document.body.appendChild(el);
+ el.select();
+ document.execCommand("copy");
+
+ resolve();
+ } catch (err) {
+ reject(err);
+ } finally {
+ document.body.removeChild(el);
+ }
+ });
+ }
+}
+
+if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks);
+} else {
+ addCopyButtonCallbacks();
+}
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function () {
+ $("#documenter .docs-navbar").headroom({
+ tolerance: { up: 10, down: 10 },
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+$(document).ready(function () {
+ let meta = $("div[data-docstringscollapsed]").data();
+
+ if (meta?.docstringscollapsed) {
+ $("#documenter-article-toggle-button").trigger({
+ type: "click",
+ noToggleAnimation: true,
+ });
+ }
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+/*
+To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc
+
+PSEUDOCODE:
+
+Searching happens automatically as the user types or adjusts the selected filters.
+To preserve responsiveness, as much as possible of the slow parts of the search are done
+in a web worker. Searching and result generation are done in the worker, and filtering and
+DOM updates are done in the main thread. The filters are in the main thread as they should
+be very quick to apply. This lets filters be changed without re-searching with minisearch
+(which is possible even if filtering is on the worker thread) and also lets filters be
+changed _while_ the worker is searching and without message passing (neither of which are
+possible if filtering is on the worker thread)
+
+SEARCH WORKER:
+
+Import minisearch
+
+Build index
+
+On message from main thread
+ run search
+ find the first 200 unique results from each category, and compute their divs for display
+ note that this is necessary and sufficient information for the main thread to find the
+ first 200 unique results from any given filter set
+ post results to main thread
+
+MAIN:
+
+Launch worker
+
+Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results)
+
+On text update
+ if worker is not running, launch_search()
+
+launch_search
+ set worker_is_running to true, set last_search_text to the search text
+ post the search query to worker
+
+on message from worker
+ if last_search_text is not the same as the text in the search field,
+ the latest search result is not reflective of the latest search query, so update again
+ launch_search()
+ otherwise
+ set worker_is_running to false
+
+ regardless, display the new search results to the user
+ save the unfiltered_results as a global
+ update_search()
+
+on filter click
+ adjust the filter selection
+ update_search()
+
+update_search
+ apply search filters by looping through the unfiltered_results and finding the first 200
+ unique results that match the filters
+
+ Update the DOM
+*/
+
+/////// SEARCH WORKER ///////
+
+function worker_function(documenterSearchIndex, documenterBaseURL, filters) {
+ importScripts(
+ "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js"
+ );
+
+ let data = documenterSearchIndex.map((x, key) => {
+ x["id"] = key; // minisearch requires a unique for each object
+ return x;
+ });
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ const stopWords = new Set([
+ "a",
+ "able",
+ "about",
+ "across",
+ "after",
+ "almost",
+ "also",
+ "am",
+ "among",
+ "an",
+ "and",
+ "are",
+ "as",
+ "at",
+ "be",
+ "because",
+ "been",
+ "but",
+ "by",
+ "can",
+ "cannot",
+ "could",
+ "dear",
+ "did",
+ "does",
+ "either",
+ "ever",
+ "every",
+ "from",
+ "got",
+ "had",
+ "has",
+ "have",
+ "he",
+ "her",
+ "hers",
+ "him",
+ "his",
+ "how",
+ "however",
+ "i",
+ "if",
+ "into",
+ "it",
+ "its",
+ "just",
+ "least",
+ "like",
+ "likely",
+ "may",
+ "me",
+ "might",
+ "most",
+ "must",
+ "my",
+ "neither",
+ "no",
+ "nor",
+ "not",
+ "of",
+ "off",
+ "often",
+ "on",
+ "or",
+ "other",
+ "our",
+ "own",
+ "rather",
+ "said",
+ "say",
+ "says",
+ "she",
+ "should",
+ "since",
+ "so",
+ "some",
+ "than",
+ "that",
+ "the",
+ "their",
+ "them",
+ "then",
+ "there",
+ "these",
+ "they",
+ "this",
+ "tis",
+ "to",
+ "too",
+ "twas",
+ "us",
+ "wants",
+ "was",
+ "we",
+ "were",
+ "what",
+ "when",
+ "who",
+ "whom",
+ "why",
+ "will",
+ "would",
+ "yet",
+ "you",
+ "your",
+ ]);
+
+ let index = new MiniSearch({
+ fields: ["title", "text"], // fields to index for full-text search
+ storeFields: ["location", "title", "text", "category", "page"], // fields to return with results
+ processTerm: (term) => {
+ let word = stopWords.has(term) ? null : term;
+ if (word) {
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ word = word
+ .replace(/^[^a-zA-Z0-9@!]+/, "")
+ .replace(/[^a-zA-Z0-9@!]+$/, "");
+
+ word = word.toLowerCase();
+ }
+
+ return word ?? null;
+ },
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not
+ // find anything if searching for "add!", only for the entire qualification
+ tokenize: (string) => string.split(/[\s\-\.]+/),
+ // options which will be applied during the search
+ searchOptions: {
+ prefix: true,
+ boost: { title: 100 },
+ fuzzy: 2,
+ },
+ });
+
+ index.addAll(data);
+
+ /**
+ * Used to map characters to HTML entities.
+ * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts
+ */
+ const htmlEscapes = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ };
+
+ /**
+ * Used to match HTML entities and HTML characters.
+ * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts
+ */
+ const reUnescapedHtml = /[&<>"']/g;
+ const reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+ /**
+ * Escape function from lodash
+ * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts
+ */
+ function escape(string) {
+ return string && reHasUnescapedHtml.test(string)
+ ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr])
+ : string || "";
+ }
+
+ /**
+ * RegX escape function from MDN
+ * Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
+ */
+ function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+ }
+
+ /**
+ * Make the result component given a minisearch result data object and the value
+ * of the search input as queryString. To view the result object structure, refer:
+ * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult
+ *
+ * @param {object} result
+ * @param {string} querystring
+ * @returns string
+ */
+ function make_search_result(result, querystring) {
+ let search_divider = `
`;
+ let display_link =
+ result.location.slice(Math.max(0), Math.min(50, result.location.length)) +
+ (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div
+
+ if (result.page !== "") {
+ display_link += ` (${result.page})`;
+ }
+ searchstring = escapeRegExp(querystring);
+ let textindex = new RegExp(`${searchstring}`, "i").exec(result.text);
+ let text =
+ textindex !== null
+ ? result.text.slice(
+ Math.max(textindex.index - 100, 0),
+ Math.min(
+ textindex.index + querystring.length + 100,
+ result.text.length
+ )
+ )
+ : ""; // cut-off text before and after from the match
+
+ text = text.length ? escape(text) : "";
+
+ let display_result = text.length
+ ? "..." +
+ text.replace(
+ new RegExp(`${escape(searchstring)}`, "i"), // For first occurrence
+ '$&'
+ ) +
+ "..."
+ : ""; // highlights the match
+
+ let in_code = false;
+ if (!["page", "section"].includes(result.category.toLowerCase())) {
+ in_code = true;
+ }
+
+ // We encode the full url to escape some special characters which can lead to broken links
+ let result_div = `
+
+
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.
Create movies for representation of earthquake or wave propagation.
Create geodynamic input models (for LaMEM)
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
diff --git a/dev/man/Tutorial_AlpineData/index.html b/dev/man/Tutorial_AlpineData/index.html
new file mode 100644
index 00000000..8f26b355
--- /dev/null
+++ b/dev/man/Tutorial_AlpineData/index.html
@@ -0,0 +1,132 @@
+
+18 - Alpine data integration · GeophysicalModelGenerator.jl
Process and unify these datasets with GeophysicalModelGenerator
Save the resulting dataset
Export the datasets to Paraview
This is a rather lengthy tutorial that combines different other tutorials, but it will guide you through all the steps necessary to obtain a somewhat comprehensive view of the European Alps and their subsurface from a geodynamical point of view.
In many cases, we want to add topographic data to our visualization. Here we use GMT.jl to download data from a certain region, and transfer that to GMG. To add the GMT package, simply add it with the julia package manager:
julia> ]
+(@v1.10) pkg> add GMT
and load both GMG and GMT with:
using GeophysicalModelGenerator, GMT
When loading both packages, several GMT routines within GMG will be loaded. One of these routines is the function import_topo, where one simply has to provide the region for which to download the topographic data and the data source.
The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area, as the files become very large.
If you have issues with loading the topography with GMT, there is also the alternative to download the data yourself and import it using Rasters.jl.
We can now export this data to a VTK format so that we can visualize it with Paraview. To do so, GMG provides the function write_paraview:
write_paraview(Topo, "Topography_Alps")
Also, if you want to save this data for later use in julia, you can save it as *.jld2 file using the function save_GMG:
save_GMG("Topography_Alps",Topo)
The result looks like: Note that we used the Oleron scientific colormap from here for the topography.
Here, we will use the dataset from Mroczek et al. (2023). This dataset is publicly available and can be downloaded from here. To allow for downloading such data, we use the julia package Downloads.jl, which is a dependency of GMG. To download the Moho data in the current directory, simply type:
Here the downloaded file gets the name MohoMroczek2023.dat and will be saved in the current directory. A quick look at the file shows that it contains a header consisting of 11 lines, one line with the description of the different columns and then the actual data. Have a look at the file yourself. To import the CSV file, we will use the package DelimitedFiles.jl. Have a look at its documentation to see the different import options.
using DelimitedFiles
+data_mroczek = readdlm("MohoMroczek2023.csv",',',header=false,skipstart=11)
Note that we skipped the first 11 lines of the file as they contain the file header. The result of this operation will look like this:
We are now only interested in the depth of the Moho at a given longitude/latitude. To obtain these values, we now have to extract columns 4-6. In addition, we also extract the 10th column, as it contains an identifier for the tectonic unit the respective point belongs to.
lon = zeros(size(data_mroczek,1)-1); lon .= data_mroczek[2:end,5];
+lat = zeros(size(data_mroczek,1)-1); lat .= data_mroczek[2:end,4];
+depth = zeros(size(data_mroczek,1)-1); depth .= -1.0*data_mroczek[2:end,6]; #multiplied with -1, as we consider depth to be negative
+tag = string.(data_mroczek[2:end,10]); #get unit identifiers und convert them to strings
+nothing #hide
As a next step, we determine how many different tectonic units there are:
units = unique(tag) #get different units
We will use these units later to save the Moho data separately for each tectonic unit.
To convert this data to a GMG dataset, we now have to interpolate it to a regular grid. You can generate the respective grid with the GMG function lonlatdepth_grid
To interpolate the Moho data of the different units to this grid, we have here decided to employ a simple Nearest Neighbor interpolation for simplicity.
using NearestNeighbors
!!! note Interpolating data is tricky and may result in unnecessary smoothing of the data. There are different ways to interpolate data on a regular grid. Have a look at our data interpolation tutorial to see the different possibilities.
Now that we have generated the grid, we can loop over our different tectonic units, extract the relevant data points and interpolate them to the regular grid:
for iunit = 1:length(units)
+ Dist = zeros(size(Lon))
+
+ #Get all points belonging to the unit
+ ind_unit = findall( x -> occursin(units[iunit], x), tag) #index of the points belonging to that unit
+ lon_tmp = lon[ind_unit]
+ lat_tmp = lat[ind_unit]
+ depth_tmp = depth[ind_unit]
+
+ #for later checking, we can now save the original point data as a VTK file:
+ data_Moho = GeophysicalModelGenerator.GeoData(lon_tmp,lat_tmp,depth_tmp,(MohoDepth=depth_tmp*km,))
+ filename = "Mroczek_Moho_" * units[iunit]
+ write_paraview(data_Moho, filename, PointsData=true)
+
+ #Now we create a KDTree for an effective nearest neighbor determination;
+ kdtree = KDTree([lon_tmp';lat_tmp']; leafsize = 10)
+ points = [Lon[:]';Lat[:]']
+ idxs, dists = knn(kdtree, points, 1, true) #get the distance to the nearest data point
+ dists = reduce(vcat,dists)
+ idxs = reduce(vcat,idxs)
+ idxs = reduce(vcat,idxs)
+
+ #Having determined the nearest neighbor for each point in our regular grid, we can now directly assign the respective depth. Whenever the nearest neighbor is further than a certain distance away, we assume that there is no Moho at this point and do not assign a depth to that point.
+ for i=1:length(idxs)
+ if dists[i]<0.02
+ Depth[i] = depth_tmp[idxs[i]]*km
+ else
+ Depth[i] = NaN*km
+ end
+ Dist[i] = dists[i]
+ end
+
+ #As we will be using the data later, we would also like to provide some Metadata so that we know where it is coming from:
+ Data_attribs = Dict(
+ "author"=> "Mroczek et al.",
+ "year"=> "2023",
+ "doi"=>"https://doi.org/10.5880/GFZ.2.4.2021.009",
+ "url"=>"https://nextcloud.gfz-potsdam.de/s/zB5dPNby6X2Kjnj",
+ )
+
+ #Finally, we can now export that data to VTK and save a `jld2` file using the `save_GMG` routine
+ Data_Moho = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (MohoDepth=Depth,PointDist=Dist),Data_attribs)
+ filename = "Mrozek_Moho_Grid_" * units[iunit]
+ write_paraview(Data_Moho, filename)
+ save_GMG(filename,Topo)
+
+end
Just for checking, we can also plot both the original data and the resulting interpolated Moho:
ISC provides a method to download parts of it's catalogue via a web interface. See the description of the interface here. We will now download all reviewed earthquake data between 1990 and 2015 in the same region as the extracted topography. We will only consider earthquakes with a magnitude larger than 3. The resulting dataset is quite large, so consider to either limit the time range or the magnitude range.
Once the data has been downloaded, we can extract lon/lat/depth/magnitude using the GMG function getlonlatdepthmag_QuakeML, which returns a GeoData structure:
As before, we can export this dataset to VTK and also save it as a jld2 file (as we are now exporting point data, we have to use the option PointsData=true):
Besides data on the structure of the subsurface, it is also nice to see the dynamics of a region. Dynamic processes can be nicely seen in the surface velocities given by GPS data. As GPS data consists of three-dimensional vectors, we have to treat it differently than the seismicity data in the previous section. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7.
The data related to the paper can be downloaded from: here. There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example, and will therefore download the following data sets:
Next, we will load the data. As above, we will use DelimitedFiles.jl to load the data. Let's first start with the vertical velocities, which are stored in ALPS2017_DEF_VT.GRD. If we open that file with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees] Column 2: Latitude [degrees] Column 3: Velocity in the height direction [m/a] Column 4: Uncertainty of the height component [m/a]
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in Paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
Now that we have imported the vertical velocities, let's do the same for the horizontal ones. Again looking at the data, we see that it starts at line 19 and is organized as follows: Column 1: Longitude [degrees]Column 2: Latitude [degrees]Column 3: East component of the deformation [m/a]Column 4: North component of the deformation [m/a]Column 5: Uncertainty of the east component [m/a]Column 6: Uncertainty of the north component [m/a]
Let's load the data again and extract the relevant data:
Let's have a look at how the data points of this dataset are distributed:
Plots.scatter(lon_vh,lat_vh)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in regions which are covered with water. This thus requires a bit more work to transfer them to a rectangular grid. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz initialized with NaN (not a number).
Ve = fill(NaN,size(Vz));
+Vn = fill(NaN,size(Vz));
+nothing #hide
Next, we loop over all points in lon_Hz,lat_Hz and place them into 2D matrixes:
for i in eachindex(lon_vh)
+ ind = intersect(findall(x->x==lon_vh[i], Lon), findall(x->x==lat_vh[i], Lat))
+ Ve[ind] .= ve[i];
+ Vn[ind] .= vn[i];
+end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly. Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. As we have already the loaded the topographic map in section 1 of this tutorial, we can simply reuse it. To interpolate, we will use the function interpolate_datafields_2D
The variable we are interested in is the variable topo_v. fields_v contains the interpolation of all the fields in Topo to the new grid and we only keep it here for completeness. Note that as the topography in the Topo variable is in km, topo_v will also be given the unit of km. Next, we have to combine the data in a GeoData structure. The velocities are specified as a Tuple (called Velocity_mm_year), which is interpreted a vector when saving this to Paraview.
Finally, we'd like to have a look at the subsurface by looking at a seismic tomography. To do so, we'll first download the tomography published by Rappisi et al.(2022). The data is provided as NetCDF files:
Finally, as we would like to keep the information on the data source, we add this information as a dictionary.
Data_attribs = Dict(
+ "author"=> "Rappisi, F. and VanderBeek, B. P. and Faccenda, M. and Morelli, A. and Molinari, I.",
+ "title" => "Slab Geometry and Upper Mantle Flow Patterns in the Central Mediterranean From 3D Anisotropic P-Wave Tomography",
+ "journal"=>"Journal of Geophysical Research: Solid Earth",
+ "volume"=>127,
+ "number"=>5,
+ "pages"=>"e2021JB023488",
+ "doi"=>"https://doi.org/10.1029/2021JB023488",
+ "url"=>"https://doi.org/10.1029/2021JB023488",
+ "year"=>2022
+)
Now we are all set and can create a GeoData structure which along with metadata
Data = GeoData(Lon,Lat,Depth[:,:,:],(Vp=Vp[:,:,:],dVp=dlnVp[:,:,:]),Data_attribs);
+nothing #hide
For the sake of this tutorial, we have now imported all the data we would like to look at. All that is missing is now a joint visualization of these datasets. To obtain this visualization, we will load all the VTK files into Paraview and have a look:
A Paraview statefile that reproduces this visualization is available under tutorials/Tutorial_AlpineData.pvsm.
We start with loading the package, and assume that you have installed it:
using GeophysicalModelGenerator;
Lets load a first 3D seismic tomography data set of the Alps. We uploaded an example file on Zenodo here, which comes from the paper of Paffrath et al. 2021. We can load this in GMG with:
This is a so-called GeoData object, which is a 3D grid of seismic velocities as a function of longitude, latitude and depth, which can include various fields (here we only have a single field: :dVp_Percentage) We can save this in VTK format, which is a widely used format that can for exampke be read by the 3D open-source visualization tool Paraview:
write_paraview(Tomo_Alps_full,"Tomo_Alps_full")
Saved file: Tomo_Alps_full.vts
+
We also uploaded a dataset with the topography of the Alpine region which can be downloaded with:
Different than the 3D tomographic model, the topography has size 1 for the last index which indicates that this is a 3D surface. As you can see, the depth varies, which is because it is a warped surface. We can write this to disk as well
write_paraview(Topo_Alps,"Topo_Alps")
Saved file: Topo_Alps.vts
+
If we open both datasets in Paraview, and changing both files from outline/solid colors to the corresponding data field, we see: Now we can change the colormap on the right side, marked by a red square. For topography we use the Oleron colormap, which you can download here. For the tomography we use the Roma scientific colormap. You will now see a blue'ish box of the tomography, this is not the best color to visualise the data. Let's invert the colormap by clicking on the item marked by the blue arrow. Now we see the tomography in a more intuitive way, but the topography is not visible anymore. We can change the opacity of the tomography by setting a value in the Opacity field marked by the red square. Note that you will need to adapt the range of the topography colormap as the change in color is not at 0.0. By clicking on the item marked by the black arrow, you can set your desired range.
As you can see the tomographic data covers a much larger area than the Alps itself, and in most of that area there is no data. It is thus advantageous to cut out a piece of the dataset that we are interested in which can be done with extract_subvolume:
Paraview has the option to Slice through the data but it is not very intuitive to do this in 3D. Another limitation of Paraview is that it does not have native support for spherical coordinates, and therefore the data is translated to cartesian (x,y,z) coordinates (with the center of the Earth at (0,0,0)). That makes this a bit cumbersome to make a cross-section at a particular location. If you are interested in this you can use the cross_section function:
As you see, this is not exactly at 200 km depth, but at the closest z-level in the data sets. If you want to be exactly at 200 km, use the Interpolate option:
In general, you can get help info for all functions with ?:
help?> cross_section
+search: cross_section cross_section_volume cross_section_points cross_section_surface flatten_cross_section
+
+ cross_section(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)
+
+ Creates a cross-section through a GeoData object.
+
+ • Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
+
+ • They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
+
+ • Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
+
+ 1. Volume data: data will be interpolated or directly extracted from the data set.
+
+ 2. Surface data: surface data will be interpolated or directly extracted from the data set
+
+ 3. Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
+
+ • Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA
+ SETS
+
+ • 'section_width' indicates the maximal distance within which point data will be projected to the profile
+
+ Example:
+ ≡≡≡≡≡≡≡≡
+
+ julia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);
+ julia> Data = Depth*2; # some data
+ julia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);
+ julia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));
+ julia> Data_cross = cross_section(Data_set3D, Depth_level=-100km)
+ GeoData
+ size : (11, 11, 1)
+ lon ϵ [ 10.0 : 20.0]
+ lat ϵ [ 30.0 : 40.0]
+ depth ϵ [ -100.0 km : -100.0 km]
+ fields: (:Depthdata, :LonData, :Velocity)
Let's use this to make a vertical cross-section as well:
After loading the data in Paraview, you can use the Clip tool on the topography to only show the topography above sealevel and make it 60% transparent. Also adjust the colormap of the tomography to 5.0 and -5.0
After doing all these steps, you should see something like this:
As you can see, the curvature or the Earth is taken into account here. Yet, for many applications it is more convenient to work in Cartesian coordinates (kilometers) rather then in geographic coordinates. GeophysicalModelGenerator has a number of tools for this. First we need do define a ProjectionPoint around which we project the data
Yet, because of the curvature of the Earth, the resulting 3D model is not strictly rectilinear, which is often a requiment for cartesian numerical models. This can be achieved in a relatively straightforward manner, by creating a new 3D dataset that is slightly within the curved boundaries of the projected data set:
In this tutorial, your will learn how to use Chmy to perform a 2D diffusion simulation on one or multiple CPU's or GPU's. Chmy is a package that allows you to specify grids and fields and create finite difference simulations, by applying stencil-based kernels in an efficient manner.
In case you want to use GPU's, you need to sort out whether you have AMD or NVIDIA GPU's and load the package accordingly: using AMDGPU AMDGPU.allowscalar(false) using CUDA CUDA.allowscalar(false)
You need to specify compute kernel for the gradients:
@kernel inbounds = true function compute_q!(q, C, χ, g::StructuredGrid, O)
+ I = @index(Global, NTuple)
+ I = I + O
+ q.x[I...] = -χ * ∂x(C, g, I...)
+ q.y[I...] = -χ * ∂y(C, g, I...)
+end
You need to specify a compute kernel to update the concentration
@kernel inbounds = true function update_C!(C, q, Δt, g::StructuredGrid, O)
+ I = @index(Global, NTuple)
+ I = I + O
+ C[I...] -= Δt * divg(q, g, I...)
+end
And the main function is:
@views function main(backend=CPU(); nxy_l=(126, 126))
+ arch = Arch(backend, MPI.COMM_WORLD, (0, 0))
+ topo = topology(arch)
+ me = global_rank(topo)
+
+ # geometry
+ dims_l = nxy_l
+ dims_g = dims_l .* dims(topo)
+ grid = UniformGrid(arch; origin=(-2, -2), extent=(4, 4), dims=dims_g)
+ launch = Launcher(arch, grid, outer_width=(16, 8))
+
+ ##@info "mpi" me grid
+
+ nx, ny = dims_g
+ # physics
+ χ = 1.0
+ # numerics
+ Δt = minimum(spacing(grid))^2 / χ / ndims(grid) / 2.1
+ # allocate fields
+ C = Field(backend, grid, Center())
+ P = Field(backend, grid, Center(), Int32) # phases
+
+ q = VectorField(backend, grid)
+ C_v = (me==0) ? KernelAbstractions.zeros(CPU(), Float64, size(interior(C)) .* dims(topo)) : nothing
+
+ # Use the `GeophysicalModelGenerator` to set the initial conditions. Note that
+ # you have to call this for a `Phases` and a `Temp` grid, which we call `C` here.
+ add_box!(P,C,grid, xlim=(-1.0,1.0), zlim=(-1.0,1.0), phase=ConstantPhase(4), T=ConstantTemp(400))
+
+ # set BC's and updates the halo:
+ bc!(arch, grid, C => Neumann(); exchange=C)
+
+ # visualisation
+ fig = Figure(; size=(400, 320))
+ ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="it = 0")
+ plt = heatmap!(ax, centers(grid)..., interior(C) |> Array; colormap=:turbo)
+ Colorbar(fig[1, 2], plt)
+ # action
+ nt = 100
+ for it in 1:nt
+ (me==0) && @printf("it = %d/%d \n", it, nt)
+ launch(arch, grid, compute_q! => (q, C, χ, grid))
+ launch(arch, grid, update_C! => (C, q, Δt, grid); bc=batch(grid, C => Neumann(); exchange=C))
+ end
+ KernelAbstractions.synchronize(backend)
+ gather!(arch, C_v, C)
+ if me == 0
+ fig = Figure(; size=(400, 320))
+ ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel="x", ylabel="y", title="it = 0")
+ plt = heatmap!(ax, C_v; colormap=:turbo) # how to get the global grid for axes?
+ Colorbar(fig[1, 2], plt)
+ save("out_gather_$nx.png", fig)
+ end
+ return
+end
which works just like any of the other GMG function, except that you pass Chmy Scalar Fields and a Chmy grid object. Note that this also works in MPI-parallel.
In this tutorial, Fault Data is loaded as Shapefiles, which is then transformed to raster data. With the help of that a fault density map of Europe is created.
using GeophysicalModelGenerator, Shapefile, Plots, Rasters, GeoDatasets, Interpolations
Data is taken from "Active Faults of Eurasia Database AFEAD v2022" DOI:10.13140/RG.2.2.25509.58084 You need to download it manually (as it doesn't seem to work automatically), and can load the following file:
Create a density map of the fault data. This is done with the countmap function. This function takes a specified field of a 2D GeoData struct and counts the entries in all control areas which are defined by steplon (number of control areas in lon direction) and steplat (number of control areas in lat direction). The field should only consist of 0.0 and 1.0 and the steplength. The final result is normalized by the highest count.
In this tutorial, your will learn how to use drape a geological map on top of a digital topography model, import GeoTIFF surfaces and add cross-sections from screenshots to the model setup.
Next, we drape the geological map on top of the geological map. The geological map was taken from the 2021 PhD thesis of Marc Schori and saved as png map. We downloaded the pdf map, and cropped it to the lower left and upper right corners. The resulting map was uploaded to zenodo; it can be downloaded with
We also used a slightly larger version of the map along with the online tool https://apps.automeris.io to extract the location of the corners (using the indicated blue lon/lat values on the map as reference points). This results in:
In the same PhD thesis, Schori also reconstructed the depth of various layers within the Jura. The data of his thesis are uploaded to https://doi.org/10.5281/zenodo.5801197. Here, we use the basement topography as an example (/03_BMes_top-basement/BMes_Spline.tif), which is in the GeoTIFF format that contains coordinates. Unfortunately, there are a lot of coordinate systems and in the thesis of Schori, a mixture of longitude/latitude (longlat) and a Swiss reference system is used. Within GeophysicalModelGenerator, we need a longlat coordinate system. It is quite easy to convert one to the other with the open-source QGIS package. We did this and saved the resulting image in Zenodo:
the removeNaN_z option removes NaN values from the dataset and instead uses the z-value of the nearest point. That is important if you want to use this surface to generate a 3D model setup (using below_surface, for example).
The thesis also provides a few interpreted vertical cross-sections. As before, we import them as a screenshot and estimate the lower-left and upper right corners. In this particular case, we are lucky that the lon/lat values are indicated on the cross-section. Often that is not the case and you have to use the mapview along with the digitizer tool described above to estimate this.
As example, we use the cross-section
download_data("https://zenodo.org/records/10726801/files/Schori_2020_Ornans-Miserey-v2_whiteBG.png", "Schori_2020_Ornans-Miserey-v2_whiteBG.png")
+Corner_LowerLeft = (5.92507, 47.31300, -2.0)
+Corner_UpperRight = (6.25845, 46.99550, 2.0)
+CrossSection_1 = screenshot_to_GeoData("Schori_2020_Ornans-Miserey-v2_whiteBG.png", Corner_LowerLeft, Corner_UpperRight) # name should have "colors" in it
Note that we slightly modified the image to save it with a white instead of a transparent background
At this stage, we have all data in geographic coordinates. In most cases it is more useful to have them in cartesian coordinates. Moreover, the resolution of the grids is different. Whereas the TopoGeology has a size of (3721, 2641, 1), Basement has size (2020, 1751, 1). It is often useful to have them on exactly the same size grid
We can do this in two steps: First, we define a ProjectionPoint along which we perform the projection
proj = ProjectionPoint(Lon=6, Lat=46.5)
We can simply transfer the TopoGeology map to Cartesian values with:
The problem is that the result is not strictly orthogonal, but instead slightly curved. That causes issues later on when we want to intersect the surface with a 3D box. It is therefore better to use the project_CartData to project the GeoData structure to a CartData struct. Let's first create this structure by using x,y coordinates that are slightly within the ranges given above:
for visualization, it is nice if we can remove the part of the cross-section that is above the topography. We can do that with the below_surface routine which returns a Boolean to indicate whether points are below or above the surface
Yet, if you want to perform a numerical simulation of the Jura, it is more convenient to rotate the maps such that we can perform a simulation perpendicular to the strike of the mountain belt. This can be done with rotate_translate_scale:
We use a vertical exaggeration of factor two. Also note that the y-direction is now perpendicular to the Jura mountains. The paraview statefiles to generate this figure is /tutorials/Jura_2.pvsm.
In this tutorial, your will learn how to use real data to create a geodynamic model setup in CartData. We will use the data of the Cumbre Viejo eruption in La Palma, which is a volcanic island that erupted from mid september 2021 - december 2021. The seimsicity from that time-period is used as an inspiration to set the locations of magma intrusions
Next, lets load the seismicity. The earthquake data is available on https://www.ign.es/web/ign/portal/vlc-catalogo. We have filtered them and prepared a file with earthquake locations up to early November 2021 (from january 2021). Download that:
Note that this data is in geographic coordinates, which makes it non-trivial to create slices through the data (see coordinate axis in the plot, where z is not pointing upwards).
In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
proj = ProjectionPoint(Lon=-17.84, Lat=28.56)
Once this is done you can convert the topographic data to the cartesian reference frame
It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:
It is useful to plot the earthquake density in 3D, which indicates where most action is happening in the system. For this, we first create a 3D grid of the region:
This explains how to load the Moho topography for Italy and the Alps and create a paraview file. The data comes from the following publication: Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 separate ascii files and uploaded it.
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
using Plots
+scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
using GeophysicalModelGenerator
+data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
Lon, Lat, Depth = lonlatdepth_grid(4.1:0.1:11.9,42.5:.1:49,-30km)
We will use a nearest neighbor interpolation method to fit a surface through the data, which has the advantage that it will take the discontinuities into account. This can be done with nearest_point_indices
In many geodynamic models, the lithosphere consists of a crust and mantle (or upper crust, lower crust and mantle lithosphere). We can use the function LithosphericPhases for this, which is a simple way to set a lithospheric layering. The layering here is defined by the Layers and Phases arguments, where Layers is a vector of the thickness of each of the layers (counting from the top) and Phases is a vector of the phase numbers for each layer.
So far, we only created the mechanical structure but not the thermal one. We can do that by specifying a thermal structure. For example, we can use the half-space cooling model:
Let's specify an oceanic thermal profile with a mid oceanic ridge at the left. For this, we use the SpreadingRateTemp function, and specify a spreading velocity (note that this simply relates to the thermal structure and does not have to be the same as the subduction velocity you obtain in your geodynamic simulation).
So far, the subducting part of the slab was always straight. We can also create a curved slab by using the add_slab! function. This uses a parametric representation of the slab and is a bit more involved than the add_box! function.
Next, we should define a Trench structure, which contains info about the trench which goes in 3D from Start - End coordinates (x,y)-coordinates respectively. As we are dealing with a 2D model, we set the y-coordinates to -100.0 and 100.0 respectively. Other parameters to be specified are Thickness (Slab thickness), θ_max (maximum slab dip angle), Length (length of slab), and Lb length of bending zoneof slab
The add_slab! function has a few more interesting options. You can, for example, specify a weak decoupling layer above the slab which adds a weak layer between the subducting and overriding slab. You can also indicate a thermal structure for the slab, which can increase from a halfspace cooling model (of the horizontal part of the slab) to a slab that is heated by the surrounding mantle below a decouping depth d_decoupling.
Our starting basis is the example above with ridge and overriding slab
Lets start with defining the horizontal part of the overriding plate. Note that we define this twice with different thickness to deal with the bending subduction area:
Yet, now we add a trench as well. The starting thermal age at the trench is that of the horizontal part of the oceanic plate:
AgeTrench_Myrs = 800e3/(v_spread_cm_yr/1e2)/1e6 #plate age @ trench
26.666666666666668
We want to add a smooth transition from a halfspace cooling 1D thermal profile to a slab that is heated by the surrounding mantle below a decoupling depth d_decoupling.
We have a number of other functions to help create a geometry, specifically:
AddLayer!
AddSphere!
AddEllipsoid!
AddCylinder!
The help functions are quite self-explanatory, so we won't show it in detail here. If you have a topography surface or any other horizontal surface, you can surface with the cartesian grid with above_surface or below_surface.
Also, if you wish to take a seismic tomography as inspiration to set a slab geometry, you can interpolate it to a CartGrid with the same dimensions and use that with the julia findall function.
Much of the options are explained in the 2D tutorial, which can directly be transferred to 3D. Therefore, we will start with a simple subduction setup, which consists of a horizontal part that has a mid-oceanic ridge on one explained
We use a lithospheric structure, which can be specified with the LithosphericPhases structure, where you can indicate Layers (the thickness of each lithospheric layer, starting from the top), and Phases the phases of the corresponding layers. Note that if the lowermost layer has the same phase as the mantle, you can define Tlab as the lithosphere-asthenosphere boundary which will automatically adjust the phase depending on temperature
Next, lets consider a somewhat more complicated setup with curved slabs, an overriding plate and a thermal structure that transitions from half-space cooling to a slab that is heated from both sides
The starting thermal age at the trench is that of the horizontal part of the oceanic plate (which is different along-trench, given that we have 3 mid oceanic ridge segments!): We want to add a smooth transition from a halfspace cooling 1D thermal profile to a slab that is heated by the surrounding mantle below a decoupling depth d_decoupling.
Finally, it is often nice to see the deformation of the plate when it subducts. A simple way to do that is to put a stripes on top using add_stripes!, which has the same phase as the subducting crust.
Lets start with creating a 3D model setup in cartesian coordinates, which uses the CartData data structure, with a resolution of $ 128 \times 128 \times 128 $ grid points, inside the domain $\Omega \in [-100,100] \times [-100,100] \times [-110,50]$ km
Now we create an integer array that will hold the Phases information (which usually refers to the material or rock type in the simulation)
Phases = fill(0, nx, ny, nz);
And as in the previous tutorials we initialize the temperature field:
Temp = fill(1350.0, nx,ny,nz);
For simplicity, we will assume a model with thee horizontal layers with different rheology where later we add the volcano and the magmatic chamber. We use add_box! to generate the initial horizontally layered model:
Then we can add the volcanic shape using add_volcano! function. In this case the base of the volcano will be centered at $x_i = (0,0,0)$, with a height of 10 km and a 15 km radius:
Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory
The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
Everything that fulfills this criteria gets the number 1, everything else 0.
Do the same with other tomographic models (using the same criteria or a different one).
Make sure that all tomographic models are interpolated to the same grid.
Sum up the 3 models.
The resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
So how do we create Votemaps? Doing this is rather simple:
This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:
And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
write_paraview(Data_VoteMap, "VoteMap_Alps")
In paraview, this gives
You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:
Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
ASAGI is a fileformat that is used by codes such as SeisSol or ExaHype. It employs the NetCDF4 data format.
We can read ASAGI files into GMG, and write GMG datasets to ASAGI format, which makes it straightforward to use GMG to create a model setup or to couple the results of geodynamic simulations (e.g., produced by LaMEM) with codes that support ASAGI.
Writes a CartData structure Data to an ASAGI file, which can be read by SeisSol or ExaHype. You can optionally pass a tuple with fields to be written. Note that we can only write individual (scalar) fields to disk, so vector or tensor fields needs to be split first
GeophysicalModelGenerator.jl's development is coordinated by a group of principal developers, who are also its main contributors and who can be contacted in case of questions about GeophysicalModelGenerator.jl. In addition, there are contributors who have provided substantial additions or modifications. Together, these two groups form "The GeophysicalModelGenerator.jl Authors".
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
Our Standards
Examples of behavior that contributes to a positive environment for our community include:
Demonstrating empathy and kindness toward other people
Being respectful of differing opinions, viewpoints, and experiences
Giving and gracefully accepting constructive feedback
Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
The use of sexualized language or imagery, and sexual attention or advances of any kind
Trolling, insulting or derogatory comments, and personal or political attacks
Public or private harassment
Publishing others' private information, such as a physical or email address, without their explicit permission
Other conduct which could reasonably be considered inappropriate in a professional setting
Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Boris Kaus, Marcel Thielmann, or any other of the principal developers responsible for enforcement listed in Authors. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
1. Correction
Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
2. Warning
Community Impact: A violation through a single incident or series of actions.
Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
3. Temporary Ban
Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
4. Permanent Ban
Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within the community.
Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
GeophysicalModelGenerator.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact with one of the principal developers first (see Authors).
GeophysicalModelGenerator.jl and its contributions are licensed under the MIT license. As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.
Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates centered around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Example
julia> Lat = 1.0:3:10.0;
+julia> Lon = 11.0:4:20.0;
+julia> Depth = (-20:5:-10)*km;
+julia> Lon3D,Lat3D,Depth3D = lonlatdepth_grid(Lon, Lat, Depth);
+julia> Lon3D
+3×4×3 Array{Float64, 3}:
+[:, :, 1] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 2] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 3] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+julia> Lat3D
+ 3×4×3 Array{Float64, 3}:
+ [:, :, 1] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 2] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 3] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+julia> Depth3D
+ 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:
+ [:, :, 1] =
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+
+ [:, :, 2] =
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+
+ [:, :, 3] =
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+julia> Data = zeros(size(Lon3D));
+julia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))
+GeoData
+ size : (3, 4, 3)
+ lon ϵ [ 11.0 : 19.0]
+ lat ϵ [ 1.0 : 10.0]
+ depth ϵ [ -20.0 km : -10.0 km]
+ fields : (:DataFieldName,)
+ attributes: ["note"]
Data structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers
x,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
x,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.
Example
julia> x = 0:2:10
+julia> y = -5:5
+julia> z = -10:2:2
+julia> X,Y,Z = xyz_grid(x, y, z);
+julia> Data = Z
+julia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))
+CartData
+ size : (6, 11, 7)
+ x ϵ [ 0.0 km : 10.0 km]
+ y ϵ [ -5.0 km : 5.0 km]
+ z ϵ [ -10.0 km : 2.0 km]
+ fields : (:FakeData, :Data2)
+ attributes: ["note"]
CartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with
Data structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.
depth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Cartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
In order to generate numerical simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create setups.
The routines provided here have the following functionality:
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Add various geometries (spheres, cuylinders, ellipsoids)
Add lithospheric structure
Add various 1D thermal structures (and possibilities to combine them)
Adds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models
Parameters
Phase - Phase array (consistent with Grid)
Temp - Temperature array (consistent with Grid)
Grid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)
xlim - left/right coordinates of box
ylim - front/back coordinates of box
zlim - bottom/top coordinates of box
phase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()
T - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()
Examples
Example 1) Layer with constant phase and temperature
julia> Grid = read_LaMEM_inputfile("test_files/SaltModels.dat")
+LaMEM Grid:
+ nel : (32, 32, 32)
+ marker/cell : (3, 3, 3)
+ markers : (96, 96, 96)
+ x ϵ [-3.0 : 3.0]
+ y ϵ [-2.0 : 2.0]
+ z ϵ [-2.0 : 0.0]
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> write_paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Example 2) Box with halfspace cooling profile
julia> Grid = read_LaMEM_inputfile("test_files/SaltModels.dat")
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> write_paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by readLaMEMinputfile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
Calculates a 1D temperature profile [C] for variable thermal parameters including radiogenic heat source and linearly interpolates the temperature profile onto the box. The thermal parameters are defined in rheology and the structure of the lithosphere is define by LithosphericPhases().
Gmsh is a widely used 3D unstructured mesh generator that produces tetrahedral meshes which can be tagged by region. It is possible to import such meshes and use that to set region info in a GMG data set, or use it to generate pTatin input.
X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)
RHO: 3D matrix with the density at each grid point [kg/m^3]
Optional arguments:
refMod: 1D vector with the reference density for each depth. Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used. In that case, one of the corners of RHO is used as reference model.In case of "AVG" the reference model is the average of each depth slice.
lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
outName: name of the paraview output (do not include file type)
printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, the easiest way to get started is by looking at LaMEM.jl which is integrated with GMG
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Reads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using read_LaMEM_inputfile.
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
Copyright (c) 2021 Boris Kaus, Marcel Thielmann and Authors (see Authors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
diff --git a/dev/man/listfunctions/index.html b/dev/man/listfunctions/index.html
new file mode 100644
index 00000000..b0015523
--- /dev/null
+++ b/dev/man/listfunctions/index.html
@@ -0,0 +1,550 @@
+
+List of functions · GeophysicalModelGenerator.jl
Creates a CartData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.
Creates a ParaviewData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.
Structure that defines the geometry of the trench and the slab.
Parameters
Start - Start of the trench (x,y) coordinates
End - End of the trench (x,y) coordinates
n_seg - The number of segment through which the slab is discretize along the dip
Length - The length of the slab
Thickness - The thickness of the slab
Lb - Critical distance through which apply the bending angle functions Lb ∈ [0,Length];
θ_max - maximum angle of bending ∈ [0°,90°].
direction - the direction of the dip The rotation of the coordinate system is done as such that the new X is parallel to the segment. Since the rotation is anticlockwise the coordinate y has specific values: direction tells if the subduction is directed along the positive or negative direction of the new y coordinate system. In practice, it apply an additional transformation to y by multiplying it with -1 or +1;
d_decoupling - depth at which the slab is fully submerged into the mantle.
type_bending - is the type of bending angle of the slab [:Linear, :Ribe]. The angle of slab changes as a function of l (∈ [0,Length]). l is the actual distance along the slab length from the trench. In case: - :Linearmath θ(l) = ((θ_max - 0.0)/(Lb-0))*l; - :Ribemath θ(l) = θ_max*l^2*((3*Lb-2*l))/(Lb^3); which is taken from Ribe 2010 [Bending mechanics and mode selection in free subduction: a thin-sheet analysis]
For l>Lb, θ(l) = θ_max;
WeakzoneThickness - Thickness of the weakzone [km]
value = ParseValue_LaMEM_InputFile(file,keyword,type; args::String=nothing)
Extracts a certain keyword from a LaMEM input file and convert it to a certain type. Optionally, you can also pass command-line arguments which will override the value read from the input file.
Adds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models
Parameters
Phase - Phase array (consistent with Grid)
Temp - Temperature array (consistent with Grid)
Grid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)
xlim - left/right coordinates of box
ylim - front/back coordinates of box
zlim - bottom/top coordinates of box
phase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()
T - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()
Examples
Example 1) Layer with constant phase and temperature
julia> Grid = read_LaMEM_inputfile("test_files/SaltModels.dat")
+LaMEM Grid:
+ nel : (32, 32, 32)
+ marker/cell : (3, 3, 3)
+ markers : (96, 96, 96)
+ x ϵ [-3.0 : 3.0]
+ y ϵ [-2.0 : 2.0]
+ z ϵ [-2.0 : 0.0]
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> write_paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Example 2) Box with halfspace cooling profile
julia> Grid = read_LaMEM_inputfile("test_files/SaltModels.dat")
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> write_paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Adds a volcano topography (cones and truncated cones)
Parameters
Phases - Phase array (consistent with Grid)
Temp - Temperature array (consistent with Grid)
Grid - CartData
Optional Parameters
volcanic_phase - phase number of the volcano,
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
T - temperature structure of the volcano
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
Below = below_surface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
This takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the "reference" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.
function that computes the bending angle θ as a function of length along the slab l.
Parameters
θ_max = maximum bending angle Lb = length at which the function of bending is applied (Lb<=Length) l = current position within the slab type = type of bending [:Ribe,:Linear]
Computes the (x,z) coordinates of the slab top, bottom surface using the mid surface of the slab as reference.
Parameters
trench - Trench structure that contains the relevant parameters
Method
It computes it by discretizing the slab surface in n_seg segments, and computing the average bending angle (which is a function of the current length of the slab). Next, it compute the coordinates assuming that the trench is at 0.0, and assuming a positive θ_max angle.
compute_thermal_structure(Temp, X, Y, Z, Phase, s::LinearWeightedTemperature)
Weight average along distance
Do a weight average between two field along a specified direction
Given a distance (could be any array, from X,Y) -> the weight of F1 increase from the origin, while F2 decreases.
This function has been conceived for averaging the solution of McKenzie and half space cooling models, but it can be used to smooth the temperature field from continent ocean:
Select the boundary to apply;
transform the coordinate such that dist represent the perpendicular direction along which you want to apply this smoothening and in a such way that 0.0 is the point in which the weight of F1 is equal to 0.0;
compute_thermal_structure(Temp, X, Y, Z, Phase, s::McKenzie_subducting_slab)
Compute the temperature field of a McKenzie_subducting_slab. Uses the analytical solution of McKenzie (1969) ["Speculations on the consequences and causes of plate motions"]. The functions assumes that the bottom of the slab is the coordinate Z=0. Internally the function shifts the coordinate.
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Takes a 2D GeoData struct and counts entries of field per predefined control area. field should only consist of 1.0s and 0.0s. The control area is defined by steplon and steplat. steplon is the number of control areas in longitude direction and steplat the number of control areas in latitude direction. The counts per control area are normalized by the highest count.
Grid = create_CartGrid(; size=(), x = nothing, z = nothing, y = nothing, extent = nothing, CharDim = nothing)
Creates a 1D, 2D or 3D cartesian grid of given size. Grid can be created by defining the size and either the extent (length) of the grid in all directions, or by defining start & end points (x,y,z). If you specify CharDim (a structure with characteristic dimensions created with GeoParams.jl), we will nondimensionalize the grd before creating the struct.
Spacing is assumed to be constant in a given direction
This can also be used for staggered grids, as we also create 1D vectors for the central points. The points you indicate in size are the corner points.
Note: since this is mostly for solid Earth geoscience applications, the second dimension is called z (vertical)
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
Creates a cross-section through a volumetric 3D dataset VolData with the data supplied in Profile. Depth_extent can be the minimum & maximum depth for vertical profiles
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
Volume data: data will be interpolated or directly extracted from the data set.
Surface data: surface data will be interpolated or directly extracted from the data set
Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS
'section_width' indicates the maximal distance within which point data will be projected to the profile
function cross_section_points(P::GeoData; Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, section_width=50 )
Creates a projection of separate points (saved as a GeoData object) onto a chosen plane. Only points with a maximum distance of section_width are taken into account
Creates a cross-section through a surface (2D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points. Start and End points will be in km!
IMPORTANT: The surface to be extracted has to be given as a gridded GeoData object. It may also contain NaNs where it is not defined. Any points lying outside of the defined surface will be considered NaN.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
When both Start=(lon,lat) & End=(lon,lat) are given, one can also provide a the depth extent of the profile by providing Depthextent=(depthmin,depth_max)
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Depth_extent is an optional parameter that can indicate the depth extent over which you want to interpolate the vertical cross-section. Default is the full vertical extent of the 3D dataset
Downloads a remote dataset with name url from a remote location and saves it to the current directory. If download fails, we make maxattempts attempts before giving up.
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
flatten_cross_section(V::GeoData)
+This function takes a 3D cross section through a GeoData structure and computes the distance along the cross section for later 2D processing/plotting
+```julia-repl
+julia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);
+julia> Data = Depth*2; # some data
+julia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);
+julia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));
+julia> Data_cross = cross_section(Data_set3D, Start=(10,30),End=(20,40))
+julia> x_profile = flatten_cross_section(Data_cross)
+julia> Data_cross = addfield(Data_cross,"x_profile",x_profile)
+
+```
Reads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.
Data = getlonlatdepthmag_QuakeML(filename::String)
Extracts longitude, latitude, depth and magnitude from a QuakeML file that has been e.g. downloaded from ISC. The data is then returned in GeoData format.
Checks if a point given by x and y is in or on (both cases return true) a polygon given by PolyX and PolyY, iSteps and jSteps provide the connectivity between the polygon edges. This function should be used through inpolygon!().
Checks if points given by matrices X and Y are in or on (both cases return true) a polygon given by PolyX and PolyY. Boolean fast will trigger faster version that may miss points that are exactly on the edge of the polygon. Speedup is a factor of 3.
Interpolates a data field Original on a 2D CartData grid New. Typically used for horizontal surfaces.
Note: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by
Interpolates a 3D data set V with a projection point proj=(Lat, Lon) on a plane defined by x and y, where x and y are uniformly spaced. Returns the 2D array Surf_interp.
Interpolates a data field Original on a 2D GeoData grid New. Typically used for horizontal surfaces.
Note: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
Loads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it. We make maxattempts attempts to download it before giving up.
Location: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with "http".
Type: type of the dataset (Volume, Surface, Point, Screenshot)
Active: Do we want this file to be loaded or not? Optional parameter that defaults to true
make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = ".vts", time = nothing)
In case one has a list of *.vtk files, this routine creates a *.pvd file that can be opened in Paraview. This is useful if you previously saved vtk files but didnt save it as a collection in the code itself.
Optional options
dir: directory where the *.vtk are stored.
pvd_name: filename of the resulting *.pvd file without extension; if not specified, full_simulation is used.
files: Vector of the *.vtk files without extension; if not specified, all *.vtk files in the directory are used.
file_extension: file extension of the vtk files. Default is .vts but all vt* work.
time: Vector of the timesteps; if not specified, pseudo time steps are assigned.
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by readLaMEMinputfile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
The typical way to create animations with Paraview is to use the Save Animation option to save a series of *.png images.
This function combines these images to an *.mp4 movie.
Optional options
dir: directory where the images are stored.
file: filename of the image series without extension and numbers. Required if >1 image series is stored in the same directory. By default we reconstruct this name from the available files.
outfile: filename of the resulting movie without extension; if not specified, file is used.
framerate: number of frames/second.
copy_to_current_dir: copies the final movie to the current directory if true (default); otherwise it will be stored in dir.
type: type of movie that is created; possible options are:
:mp4_default: Default option that saves a well-compressed mp4 movie that works well for us on ipad and embedded in a powerpoint presentation.
:mov_hires: Higher-resolution quicktime movie (larger filesize & not compatible with windows)
collect: suppresses output of FFMPEG if true (default).
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the write_paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = movie_paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = write_paraview(Data, name, pvd=movie, time=itime)
+end
+movie_paraview(pvd=movie, Finalize=true)
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers
Example
This example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = parse_columns_CSV(data_file, 4)
This uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Reads a VTR (structured grid) VTK file fname and extracts the coordinates, data arrays and names of the data. In general, this only contains a piece of the data, and one should open a *.pvtr file to retrieve the full data
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using read_LaMEM_inputfile.
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
In-place conversion of velocities in spherical velocities [Veast, Vnorth, Vup] to cartesian coordinates (for use in paraview).
NOTE: the magnitude of the vector will be the same, but the individual [Veast, Vnorth, Vup] components will not be retained correctly (as a different [x,y,z] coordinate system is used in paraview). Therefore, if you want to display or color that correctly in Paraview, you need to store these magnitudes as separate fields
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)
RHO: 3D matrix with the density at each grid point [kg/m^3]
Optional arguments:
refMod: 1D vector with the reference density for each depth. Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used. In that case, one of the corners of RHO is used as reference model.In case of "AVG" the reference model is the average of each depth slice.
lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
outName: name of the paraview output (do not include file type)
printing: activate printing of additional information [true or false]
Writes a CartData structure Data to an ASAGI file, which can be read by SeisSol or ExaHype. You can optionally pass a tuple with fields to be written. Note that we can only write individual (scalar) fields to disk, so vector or tensor fields needs to be split first
Writes a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd
Takes a GMG GeoData object of a topographic map and routes water through the grid. Optionally, you can specify rainfall in which case we accumulate the rain as specified in this 2D array instead of the cellarea. This allows you to, for example, sum, up water if you have variable rainfall in the area. The other options are as in the waterflows function of the package WhereTheWaterFlows.
Example
# Download some topographic data
+julia> Topo = import_topo([6.5,7.3,50.2,50.6], file="@earth_relief_03s");
+
+# Flow the water through the area:
+julia> Topo_water, sinks, pits, bnds = waterflows(Topo)
+julia> Topo_water
+GeoData
+ size : (961, 481, 1)
+ lon ϵ [ 6.5 : 7.3]
+ lat ϵ [ 50.2 : 50.59999999999999]
+ depth ϵ [ 0.045 : 0.724]
+ fields : (:Topography, :area, :slen, :dir, :nout, :nin, :c)
+
We have two routines to help create movies from the results. The first one takes *.png images generated with the Save Animation option in paraview and puts them together in compressed movies (either mp4 or mov):
The typical way to create animations with Paraview is to use the Save Animation option to save a series of *.png images.
This function combines these images to an *.mp4 movie.
Optional options
dir: directory where the images are stored.
file: filename of the image series without extension and numbers. Required if >1 image series is stored in the same directory. By default we reconstruct this name from the available files.
outfile: filename of the resulting movie without extension; if not specified, file is used.
framerate: number of frames/second.
copy_to_current_dir: copies the final movie to the current directory if true (default); otherwise it will be stored in dir.
type: type of movie that is created; possible options are:
:mp4_default: Default option that saves a well-compressed mp4 movie that works well for us on ipad and embedded in a powerpoint presentation.
:mov_hires: Higher-resolution quicktime movie (larger filesize & not compatible with windows)
collect: suppresses output of FFMPEG if true (default).
The other one creates *.pvd files that can be saved with the pvd=... optional option in write_paraview, such that you can animate temporal data in paraview (yif you're happy you can save the result as images and use movies_from_pics). See the corresponding tutorial on how to generate *.pvd files.
Writes a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd
We have one main routine to generate *.pvd files from existing vtk files. This is useful if no *.pvd file was generated during the simulation, or if you want to generate a *.pvd file from a collection of vtk files that were generated in different simulations. The *.pvd file can be used to animate temporal data in paraview. You can either provide a Vector of the files or the specific time step or the function reads the directory and assigns a pseudo time step to the *.pvd file.
make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = ".vts", time = nothing)
In case one has a list of *.vtk files, this routine creates a *.pvd file that can be opened in Paraview. This is useful if you previously saved vtk files but didnt save it as a collection in the code itself.
Optional options
dir: directory where the *.vtk are stored.
pvd_name: filename of the resulting *.pvd file without extension; if not specified, full_simulation is used.
files: Vector of the *.vtk files without extension; if not specified, all *.vtk files in the directory are used.
file_extension: file extension of the vtk files. Default is .vts but all vt* work.
time: Vector of the timesteps; if not specified, pseudo time steps are assigned.
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData, CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data, or combine existing paraview files into a *.pvd paraview collection (that can be used to show a movie)
Missing docstring.
Missing docstring for write_paraview. Check Documenter's build log for details.
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the write_paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = movie_paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = write_paraview(Data, name, pvd=movie, time=itime)
+end
+movie_paraview(pvd=movie, Finalize=true)
We have number of routines that makes it easier to read various datasets into GMG & create profiles through that data The routines provided here have the following functionality:
Read datasets (remote or local) that contains volumetric, surface, point, topograpy or screenshot data
Define a profile (horizontal, vertical) with space for (projected) data
Project earthquake (point) data onto the profile or intersect surfaces with a vertical profile (e.g., Moho data)
Loads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it. We make maxattempts attempts to download it before giving up.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
Volume data: data will be interpolated or directly extracted from the data set.
Surface data: surface data will be interpolated or directly extracted from the data set
Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS
'section_width' indicates the maximal distance within which point data will be projected to the profile
Location: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with "http".
Type: type of the dataset (Volume, Surface, Point, Screenshot)
Active: Do we want this file to be loaded or not? Optional parameter that defaults to true
This takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the "reference" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.
Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).
If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).
Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.
As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.
Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):
Whereas this is now in UTM Data (in meters), it is distorted.
Often it is more convenient to have this in CartData, which is done in a similar manner:
julia> Topo_Cart = convert2CartData(Topo,p)
+CartData
+ size : (165, 75, 1)
+ x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]
+ y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]
+ z ϵ [ -4.9855 km : 3.123 km]
+ fields : (:Topography,)
This shows that the model is ~5600 by 3000 km.
Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
We provide a few routines that allow exporting GMG input data sets to a format that can be read by the 3D geodynamic modelling software pTatin, which is an open-source Cartesian code to perform crustal and lithospheric-scale simulations.
The Q1Data format can be saved directly to pTatin.
We have a number of functions to deal with horizontal surfaces, which are defined as GeoData or CartData structures that have 3 dimensional flat coordinate array. Flat implies that the resolution is n by m by 1, which is required to correctly display them in paraview. The most straightforward surface is the topography (which you can obtain with import_topo). Surfaces can be added and subtracted.
Below = below_surface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers
Example
This example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = parse_columns_CSV(data_file, 4)
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
This uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
Takes a 2D GeoData struct and counts entries of field per predefined control area. field should only consist of 1.0s and 0.0s. The control area is defined by steplon and steplat. steplon is the number of control areas in longitude direction and steplat the number of control areas in latitude direction. The counts per control area are normalized by the highest count.
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It used to be tricky to get GMT.jl installed and working correctly on your system but that has improved since version 1.0 which now comes with precompiled binaries. So as long as you make sure that your GMT version is >1.0, it should work.
The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function import_topo that simplifies this. Note that this function only is available once GMT is loaded.
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example, we downloaded ETOPO1_Ice_g_gmt4 and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (to the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt.
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png:
In this tutorial, we discuss how to read the GPS data of Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7, which can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 You will also learn how to visualize them as vector data in Paraview.
Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ')
+
+num_columns = 4;
+data = parse_columns_CSV(data_file, num_columns); #Read numerical data from the file
+lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3]
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
Finally, it would be nice to put the data points on the topography. The elevation of the points is not given in the GPS dataset, so we use GMT to extract a topographic grid and interpolate the elevation on the GPS grid locations
using GMT, Interpolations
We use the import_topo function to read the topography from a file:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package CSV.jl to read in the data, and tell it that the data is separated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric formats (e.g. date, time etc.), we will use our helper function parsecolumnsCSV to only extract columns with numeric data.
This tutorial visualizes simplified geological as it is done here for a passive margin where lithospheric thinning, sedimentary basin and accretionary prism occur. The simplification is based on a polygon structure for a pseudo-3D model. While the structure can have a random shape in the x- and z-direction, in the y-direction only the extent is variable.
Before adding specific geological features, a general simplified model setup is necessary. The construction is made by using the add_box! function. For the model the discontinuities are in 15, 45, 145, and 945 km depth.
using GeophysicalModelGenerator
+
+# number of cells in every direction
+nx = 100
+ny = 100
+nz = 200
+
+# define domain size
+x = LinRange(0.0,800.0,nx)
+y = LinRange(0.0,800.0,ny)
+z = LinRange(-660,50,nz)
+Cart = CartData(xyz_grid(x, y, z))
+
+# initialize phase and temperature matrix
+Phase = fill(1,nx,ny,nz);
+Temp = fill(1350.0, nx,ny,nz);
+
+# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1
+add_box!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(-800.0,0.0), phase = LithosphericPhases(Layers=[15 30 100 800], Phases=[2 3 1 5], Tlab=1300 ), T=LinearTemp(Ttop=20, Tbot=1600))
+
+# add air phase 0
+add_box!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(0.0,50.0), phase = ConstantPhase(0), T=ConstantTemp(20.0))
To include the geological structures of a passive margin into the model, we use polygons for depths of up to 150 km. In the example, the sediment basin shows a more trapezoidal (2D in x-/z-direction) shape, while the thinning of the plate has a more triangular (2D in x-/z-direction). More complex structures can be build using arbitrarily sized polygons in x- and z-direction, wheraes in the y-direction only the length can be varied (specified by two values). The x- and z-values of the points need to be in the same order for selecting the correct point (P1(1/3), P2(2/2) –> xlim(1,2), ylim(3,2)).
# xlim: x-coordinates of the points, same ordering as zlim
+# zlim: z-coordinates of the points, same ordering as xlim
+# ylim: limits the object within the two ylim values
+# unlimited number of points possible to create the polygon
+
+# add sediment basin
+add_polygon!(Phase, Temp, Cart; xlim=(0.0,0.0, 160.0, 200.0),ylim=(100.0,300.0), zlim=(0.0,-10.0,-20.0,0.0), phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));
+
+# add thinning of the continental crust attached to the slab and its thickness
+add_polygon!(Phase, Temp, Cart; xlim=(0.0, 200.0, 0.0),ylim=(500.0,800.0), zlim=(-100.0,-150.0,-150.0), phase = ConstantPhase(5), T=LinearTemp(Ttop=1000, Tbot=1100));
+
+# add accretionary prism
+add_polygon!(Phase, Temp, Cart; xlim=(800.0, 600.0, 800.0),ylim=(100.0,800.0), zlim=(0.0,0.0,-60.0), phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));
For visualisation and comparison to actual measured data, the mode setup is saved to a paraview file.
# # Save data to paraview:
+Cart = addfield(Cart,(;Phase, Temp))
+write_paraview(Cart, "Sedimentary_basin");
After importing and looking at the file to paraview, some unresolved areas might be visible as they are visible in this model. That is due to the resolution and shape of the polygon. To reduce those artefacts an increase in resolution or a change of the polygon angle might help.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
Ideally, all data should be available in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to write_paraview. Once you are done, save it. An example showing you how this works is:
The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from:
Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004
Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:
# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)
+# when using the data please cite as:
+# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004
+X COORD (UTM Zone 32N) Y COORD (UTM Zone 32N) TOP (m.a.s.l) THICKNESS (m) DENSITY (Kg/m3)
+286635 4898615 -24823.2533 70418.125 3305
+286635 4918615 -25443.48901 69410.01563 3305
+286635 4938615 -28025.24511 66402.49219 3305
+286635 4958615 -32278.13135 61663.48438 3305
+286635 4978615 -35885.5625 57459.14063 3305
+286635 4998615 -37270.9812 55318.71094 3305
+286635 5018615 -36134.30481 55497.16406 3305
+286635 5038615 -34866.0697 55555.41406 3305
So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:
The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).
julia> res = (length(unique(ns)), length(unique(ew)), 1)
+julia> EW = reshape(ew,res)
+julia> NS = reshape(ns,res)
+julia> Depth = reshape(depth,res)
+julia> T = reshape(thick,res)
+julia> Rho = reshape(rho,res)
So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview, you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below). In paraview you can open the file and visualize it. This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section at 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at 3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
Note that using geographic coordinates is slightly cumbersome in Paraview. If your area is not too large, it may be advantageous to transfer all data to cartesian coordinates, in which case it is easier to create slices through the model. This is explained in some of the other tutorials.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the cross_section function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine extract_subvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. This can be done with the save_GMG function:
julia> save_GMG("Zhao_Pwave", Data_set)
If you, at a later stage, want to load this file again do it as follows:
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
include("Alps_VpModel_Zhao_etal_JGR2016.jl")
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
diff --git a/dev/man/tutorial_loadirregular3DSeismicData/index.html b/dev/man/tutorial_loadirregular3DSeismicData/index.html
new file mode 100644
index 00000000..fb29061a
--- /dev/null
+++ b/dev/man/tutorial_loadirregular3DSeismicData/index.html
@@ -0,0 +1,92 @@
+
+8 - Interpolate irregular 3D seismic tomography · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is separated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
diff --git a/dev/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/dev/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..129319d1
--- /dev/null
+++ b/dev/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,84 @@
+
+3 - 3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> filename = ("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regular grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the command ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
julia> using GeophysicalModelGenerator
+Lon3D,Lat3D,Depth3D = lonlatdepth_grid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:
Two shape files containing coastline and faults:
Vilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508
Earthquake data for two volcanic unrests, in 1983-84 and 2005-2016:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
De Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817
Travel time tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Ambient noise tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Load both the the shape (.shp) files contained in ./Geomorphology/*.shp inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:
To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates
Now let's plot earthquake data provided as text files. Start loading the data contained in ./SeismicLocations/*.txt. The first column gives us a temporal marker we can use to plot earthquakes in different periods.
Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in ./TravelTmeTomography/modvPS.dat for both cartesian and UTM coordinates.
Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files ./NoiseTomography/*.txt. We read them consecutively in a "for" loop:
julia> list_files = glob("AmbientNoiseTomography/*.txt");
+julia> li = size(list_files, 1);
+julia> for i = 1:li
+ nameFile = list_files[i];
+ name_vts = name_vts[24:26];
+ data = readdlm(nameFile, '\t', Float64);
+ WE = data[:,1];
+ SN = data[:,2];
+ depth = data[:,3];
+ Vs = data[:,4];
However these models are too wide, so it is better to constrain them:
findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );
+ WE = WE[ind];
+ SN = SN[ind];
+ depth = depth[ind];
+ Vs = Vs[ind];
Also, nodes are irregular, hence we create a 3D regular UTM:
This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:
Earthquake data for the 1983-84 unrest:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
You will need to download the zipped folder containing all files from here.
Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here
Create the folder TemporalSeismicity in the current folder and open the movie with the function movie_paraview.
julia> using DelimitedFiles, GeophysicalModelGenerator, Dates
+julia> p2 = @__FILE__;
+julia> p2last = findlast("/",p2);
+julia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);
+julia> output_path = string(p3,"/");
+julia> movie = movie_paraview(name=string(p3,"/TemporalSeismicity"), Initialize=true);
+julia> if isdir(string(p3,"/TemporalSeismicity"))==0
+ mkdir(string(p3,"/TemporalSeismicity"));
+ end
+
Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.
julia> data = readdlm("SeismicLocations/Seismicity_UTM_1983_1984.txt", '\t', skipstart=0, header=false);
+julia> l = length(data[:,1]);
+julia> dates = Date.(zeros(l,1))
+julia> for i = 1:l
+ df = DateFormat("yyyymmdd");
+ t1 = string("19",@sprintf("%5.o", data[i,1]));
+ t2 = Date(t1[1:8],df);
+ dates[i,1] = t2;
+ end
+julia> WE = data[:,2];
+julia> SN = data[:,3];
+julia> depth = data[:,4];
+julia> dates_num = dates - dates[1];
+
Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.
julia> nt = 50;
+julia> dt = Dates.Day(nt);
+julia> t = minimum(dates):dt:maximum(dates);
+julia> for itime = 1:length(t)-1
+ name = string(p3,"/TemporalSeismicity/", string(itime));
+ tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);
+ we = WE[tt];
+ sn = SN[tt];
+ Depth1 = depth[tt];
+ DN = dates_num[tt];
+ label_time = Dates.value(DN[end]);
+ if size(tt,1)>1
+ Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));
+ movie = write_paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);
+ end
+ end
+julia>movie_paraview(pvd=movie, Finalize=true)
This tutorial has created a new TemporalSeismicity.pvd file that can be loaded in Paraview.
Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials. We have a range of tutorials that show the functionality of GeophysicalModelGenerator.jl (see sidebar). They are mostly stand-alone so it doesn't matter in which order they are executed. The input scripts for the tutorials are available under /tutorials.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the visualise widget, which uses GLMakie and allows you to explore the data.
It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:
julia> using GeophysicalModelGenerator, GLMakie
+julia> using GMT, JLD2
The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).
julia> ;
+shell> cd ~/Downloads/Zhao_etal_2016_data/
Now you can use the backspace key to return to the REPL, where we will load the data
julia> Data = JLD2.load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp");
At this stage you can look at it with
julia> visualise(Data);
Note that this tends to take a while, the first time you do this (faster afterwards).
Let's add topography to the plot as well, which requires us to first load that:
This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.
And once we have done that, you can visualize the data in the same way:
julia> visualise(Data_Cart, Topography=Topo_Cart)
Missing docstring.
Missing docstring for visualise. Check Documenter's build log for details.
Settings
This document was generated with Documenter.jl version 1.7.0 on Monday 4 November 2024. Using Julia version 1.9.4.
diff --git a/dev/objects.inv b/dev/objects.inv
new file mode 100644
index 00000000..0dea9470
Binary files /dev/null and b/dev/objects.inv differ
diff --git a/dev/scripts/LaPalma.dat b/dev/scripts/LaPalma.dat
new file mode 100644
index 00000000..89ae7bf0
--- /dev/null
+++ b/dev/scripts/LaPalma.dat
@@ -0,0 +1,357 @@
+# Define number of elements in x, y, z-direction
+# Negative number implies corresponding number of mesh segments
+# Data is provided in the variables seg_x, seg_y, seg_z and includes:
+# * coordinates of the delimiters between the segments (n-1 points)
+# * number of cells (n points)
+# * bias coefficients (n points)
+
+
+#===============================================================================
+# Scaling
+#===============================================================================
+
+# Geometry
+units = geo
+
+# Always in SI units!!
+unit_temperature = 500
+unit_length = 1000
+unit_viscosity = 1e19
+unit_stress = 1e9
+
+#===============================================================================
+# Time stepping parameters
+#===============================================================================
+
+ dt = 5e-4 # time step
+ dt_min = 4.5e-4 # minimum time step (declare divergence if lower value is attempted)
+ dt_max = 1e-3 # maximum time step
+ inc_dt = 1 # time step increment per time step (fraction of unit)
+ CFL = 0.5 # CFL (Courant-Friedrichs-Lewy) criterion
+ CFLMAX = 0.8 # CFL criterion for elasticity
+ nstep_ini = 0 # save output for n initial steps
+ nstep_max = 20 # maximum allowed number of steps (lower bound: time_end/dt_max)
+ nstep_out = 1 # save output every n steps
+
+#===============================================================================
+# Grid & discretization parameters
+#===============================================================================
+
+# relative geometry tolerance for grid manipulations (default 1e-9)
+
+ gtol = 1e-9
+
+# Number of cells for all segments
+ nel_x = 64
+ nel_y = 64
+ nel_z = 32
+
+# Coordinates of all segments (including start and end points)
+ coord_x = -50 50
+ coord_y = -40 40
+ coord_z = -80 15
+
+#===============================================================================
+# Free surface
+#===============================================================================
+
+ surf_use = 1 # free surface activation flag
+ surf_corr_phase = 1 # air phase ratio correction flag (due to surface position)
+ surf_level = 5 # initial level
+ surf_air_phase = 0 # phase ID of sticky air layer
+ surf_max_angle = 45.0 # maximum angle with horizon (smoothed if larger)
+ surf_topo_file = LaPalma_Topo.topo # initial topography file (redundant)
+ erosion_model = 0 # erosion model [0-none (default), 1-infinitely fast]
+ sediment_model = 0 # sedimentation model [0-none (default), 1-prescribed rate]
+
+#===============================================================================
+# Boundary conditions
+#===============================================================================
+
+# noslip = 0 0 0 0 0 0
+
+ temp_top = 0 # Temperature @ top
+ temp_bot = 1350 # Temperature @ bottom; side BC's are flux-free
+
+ # Background strain rate parameters
+# exx_num_periods = 1 # number intervals of constant strain rate (x-axis)
+# exx_strain_rates = -5e-16 # strain rates for each interval (negative=compression)
+
+ # Free surface top boundary flag
+ open_top_bound = 1
+
+#===============================================================================
+# Jacobian & residual evaluation parameters
+#===============================================================================
+
+ gravity = 0.0 0.0 -9.81 # gravity vector
+ act_temp_diff = 1 # temperature diffusion activation flag
+ #act_steady_temp = 0 # steady-state temperature initial guess activation flag
+ #steady_temp_t = 0.1 # time for (quasi-)steady-state temperature initial guess
+ #nstep_steady = 50 # number of steps for (quasi-)steady-state temperature initial guess (default = 1)
+ act_heat_rech = 0 # heat recharge activation flag
+ init_lith_pres = 1 # initial pressure with lithostatic pressure
+ init_guess = 1 # initial guess flag
+ eta_min = 1e18 # viscosity upper bound
+ eta_max = 1e23 # viscosity lower limit
+ eta_ref = 1e19 # reference viscosity (initial guess)
+ T_ref = 20 # reference temperature
+
+#===============================================================================
+# Solver options
+#===============================================================================
+
+ SolverType = multigrid # solver [direct or multigrid]
+ MGLevels = 4 # number of MG levels [default=3]
+
+#===============================================================================
+# Model setup & advection
+#===============================================================================
+
+ msetup = files
+ mark_load_file = ./markers/mdb # marker input file (extension is .xxxxxxxx.dat)
+
+ #poly_file = ../Polygons/RoundTopShort_256_128_21_09_20.bin
+ nmark_x = 3 # markers per cell in x-direction
+ nmark_y = 3 # ... y-direction
+ nmark_z = 3 # ... z-direction
+# rand_noise = 1 # random noise flag
+ advect = rk2 # advection scheme
+ interp = minmod # velocity interpolation scheme
+# stagp_a = 0.7 # STAG_P velocity interpolation parameter
+ mark_ctrl = basic # marker control type
+ nmark_lim = 16 100 # min/max number per cell
+
+#===============================================================================
+# Output
+#===============================================================================
+
+# Grid output options (output is always active)
+ out_file_name = LaPalma_test # output file name
+ out_pvd = 1 # activate writing .pvd file
+ out_phase = 1
+ out_density = 1
+ out_visc_total = 1
+ out_visc_creep = 1
+ out_visc_plast = 1
+ out_velocity = 1
+ out_pressure = 1
+ out_over_press = 1
+ out_litho_press = 1
+ out_temperature = 1
+# out_dev_stress = 1
+ out_j2_dev_stress = 1
+# out_strain_rate = 1
+ out_j2_strain_rate = 1
+ out_plast_strain = 1
+ out_plast_dissip = 1
+ out_tot_displ = 1
+ out_moment_res = 1
+ out_cont_res = 1
+ out_yield = 1
+
+# AVD phase viewer output options (requires activation)
+ out_avd = 1 # activate AVD phase output
+ out_avd_pvd = 1 # activate writing .pvd file
+ out_avd_ref = 1 # AVD grid refinement factor
+
+# free surface output
+ out_surf = 1 # activate surface output
+ out_surf_pvd = 1 # activate writing .pvd file
+ out_surf_velocity = 1
+ out_surf_topography = 1
+ out_surf_amplitude = 1
+
+
+#===============================================================================
+# ............................ Material Parameters .............................
+#===============================================================================
+
+# ------------------- Air -------------------
+
+ Name = air
+ ID = 0
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Water -------------------
+
+ Name = water
+ ID = 1
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+# ------------------- Upper Crust -------------------
+
+ Name = Crust
+ ID = 2
+ rho = 2900
+ alpha = 3e-5
+
+ # dislocation viscosity
+ #disl_prof = Plagioclase_An75-Ranalli_1995
+ #disl_prof = Wet_Quarzite-Ranalli_1995
+ disl_prof = Mafic_Granulite-Ranalli_1995
+
+
+ # Elastic parameters
+ G = 3e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+
+# ------------------- Mantle lithosphere-------------------
+
+ Name = Mantle
+ ID = 3
+ rho = 3320
+ alpha = 3e-5
+
+ # dislocation viscosity
+ disl_prof = Dry_Olivine-Ranalli_1995
+
+ # Elastic parameters
+ G = 6.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3.3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Andesite -------------------
+
+ Name = magma
+ ID = 4
+ rho = 2700
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e18
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 980
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Dacite -------------------
+
+ ID = 5
+ rho = 2575
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e19
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 800
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+# End of defining material properties for all phases ----------------------------------------
+
+
+#===============================================================================
+# PETSc options
+#===============================================================================
+
+
+# SNES
+
+ -snes_npicard 5
+ -snes_max_it 200
+ -snes_rtol 1e-6
+ -snes_atol 1e-6
+ -snes_PicardSwitchToNewton_rtol 1e-7 #-7
+ #-snes_NewtonSwitchToPicard_it 1 # number of Newton iterations after which we switch back to Picard
+# -snes_monitor
+# -snes_linesearch_monitor
+
+# Jacobian solver
+ -js_ksp_type fgmres
+ -js_ksp_monitor
+ -js_ksp_max_it 30
+ -js_ksp_rtol 1e-5
+ -js_ksp_atol 1e-6
+# -js_ksp_monitor_true_residual
+
+# -its_ksp_monitor
+# -ts_ksp_monitor
+
+# Multigrid
+ -gmg_pc_mg_galerkin
+ -gmg_pc_mg_type multiplicative
+ -gmg_pc_mg_cycle_type v
+
+ -gmg_mg_levels_ksp_type richardson
+ -gmg_mg_levels_ksp_richardson_scale 0.5
+ -gmg_mg_levels_ksp_max_it 5
+ -gmg_mg_levels_pc_type jacobi
+
+ -crs_pc_factor_mat_solver_package pastix
+
+
+
diff --git a/dev/search_index.js b/dev/search_index.js
new file mode 100644
index 00000000..b515beac
--- /dev/null
+++ b/dev/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.screenshot_to_GeoData\nGeophysicalModelGenerator.screenshot_to_CartData\nGeophysicalModelGenerator.screenshot_to_UTMData\nGeophysicalModelGenerator.import_topo\nGeophysicalModelGenerator.import_GeoTIFF","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.screenshot_to_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.screenshot_to_GeoData","text":"screenshot_to_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true, fieldname::Symbol=:colors)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.screenshot_to_CartData","page":"Data Import","title":"GeophysicalModelGenerator.screenshot_to_CartData","text":"Data = screenshot_to_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as screenshot_to_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.screenshot_to_UTMData","page":"Data Import","title":"GeophysicalModelGenerator.screenshot_to_UTMData","text":"Data = screenshot_to_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true, fieldname=:colors)\n\nDoes the same as screenshot_to_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.import_topo","page":"Data Import","title":"GeophysicalModelGenerator.import_topo","text":" import_topo\n\nOptional routine that imports topography. It requires you to load GMT\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.import_GeoTIFF","page":"Data Import","title":"GeophysicalModelGenerator.import_GeoTIFF","text":" import_GeoTIFF\n\nOptional routine that imports GeoTIFF images. It requires you to load GMT\n\n\n\n\n\n","category":"function"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"EditURL = \"../../../tutorials/Tutorial_NumericalModel_3D.jl\"","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/#Creating-3D-numerical-model-setups","page":"21 - 3D model setups","title":"Creating 3D numerical model setups","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_3D/#Aim","page":"21 - 3D model setups","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"The aim of this tutorial is to show you how to create 3D numerical model setups that can be used as initial setups for other codes.","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/#3D-Subduction-setup","page":"21 - 3D model setups","title":"3D Subduction setup","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Lets start with creating a 3D model setup in cartesian coordinates, which uses the CartData data structure","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"using GeophysicalModelGenerator\n\nnx,ny,nz = 512,512,128\nx = range(-1000,1000, nx);\ny = range(-1000,1000, ny);\nz = range(-660,0, nz);\nGrid = CartData(xyz_grid(x,y,z));","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Now we create an integer array that will hold the Phases information (which usually refers to the material or rock type in the simulation)","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Phases = fill(2,nx,ny,nz);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"In many (geodynamic) models, one also has to define the temperature, so lets define it as well","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Temp = fill(1350.0, nx,ny,nz);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/#Simple-free-subduction-setup","page":"21 - 3D model setups","title":"Simple free subduction setup","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Much of the options are explained in the 2D tutorial, which can directly be transferred to 3D. Therefore, we will start with a simple subduction setup, which consists of a horizontal part that has a mid-oceanic ridge on one explained","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"We use a lithospheric structure, which can be specified with the LithosphericPhases structure, where you can indicate Layers (the thickness of each lithospheric layer, starting from the top), and Phases the phases of the corresponding layers. Note that if the lowermost layer has the same phase as the mantle, you can define Tlab as the lithosphere-asthenosphere boundary which will automatically adjust the phase depending on temperature","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"lith = LithosphericPhases(Layers=[15 45 10], Phases=[0 1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid; xlim=(-800.0,0.0), ylim=(-400, 400.0), zlim=(-80.0, 0.0), phase = lith,\n Origin=(-0,0,0),\n T=SpreadingRateTemp(SpreadingVel=3, MORside=\"right\"), StrikeAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"And an an inclined part:","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"add_box!(Phases, Temp, Grid; xlim=(0.0,300.0), ylim=(-400.0, 400.0), zlim=(-80.0, 0.0), phase = lith,\n Origin=(-0,0,0),\n T=McKenzie_subducting_slab(Tsurface=0,v_cm_yr=3), DipAngle=30, StrikeAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Add them to the CartData dataset:","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Grid = addfield(Grid,(;Phases, Temp))","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"CartData \n size : (512, 512, 128)\n x ϵ [ -1000.0 : 1000.0]\n y ϵ [ -1000.0 : 1000.0]\n z ϵ [ -660.0 : 0.0]\n fields : (:Z, :Phases, :Temp)\n","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Which looks like","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"write_paraview(Grid,\"Grid3D_FreeSubduction\");","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Saved file: Grid3D_FreeSubduction.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"(Image: Mechanical3D_Tutorial_1)","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/#More-sophisticated-setup","page":"21 - 3D model setups","title":"More sophisticated setup","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Next, lets consider a somewhat more complicated setup with curved slabs, an overriding plate and a thermal structure that transitions from half-space cooling to a slab that is heated from both sides","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"nx,ny,nz = 512,512,128\nx = range(-1000,1000, nx);\ny = range(-1000,1000, ny);\nz = range(-660,0, nz);\nGrid = CartData(xyz_grid(x,y,z));\n\nPhases = fill(2,nx,ny,nz);\nTemp = fill(1350.0, nx,ny,nz);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Overriding plate with a 30 km crust and mantle lithosphere that where T<1250 celsius","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"lith_cont = LithosphericPhases(Layers=[30 200 50], Phases=[3 4 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid; xlim=(400.0,1000.0), ylim=(-1000.0, 0.0), zlim=(-240.0, 0.0), phase = lith_cont, T=HalfspaceCoolingTemp(Age=150));\nadd_box!(Phases, Temp, Grid; xlim=(200.0,1000.0), ylim=(-1000.0, 0.0), zlim=(-80.0, 0.0), phase = lith_cont, T=HalfspaceCoolingTemp(Age=150));\n\nlith_cont = LithosphericPhases(Layers=[30 200 10], Phases=[5 6 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid; xlim=(400.0,1000.0), ylim=(0.0, 1000.0), zlim=(-240.0, 0.0), phase = lith_cont, T=HalfspaceCoolingTemp(Age=200));\nadd_box!(Phases, Temp, Grid; xlim=(200.0,1000.0), ylim=(0.0, 1000.0), zlim=( -80.0, 0.0), phase = lith_cont, T=HalfspaceCoolingTemp(Age=200));","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Define an oceanic plate with ridge","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"v_spread_cm_yr = 3 #spreading velocity\nlith = LithosphericPhases(Layers=[15 45 10], Phases=[0 1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid; xlim=(-800.0 , 200.0), ylim=(-1000.0, -400.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3));\nadd_box!(Phases, Temp, Grid; xlim=(-1000.0,-800.0), ylim=(-1000.0, -400.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3,MORside=\"right\"));\n\nadd_box!(Phases, Temp, Grid; xlim=(-700.0, 200.0), ylim=(-400.0, 200.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3));\nadd_box!(Phases, Temp, Grid; xlim=(-1000.0,-700.0), ylim=(-400.0, 200.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3,MORside=\"right\"));\n\nadd_box!(Phases, Temp, Grid; xlim=(-650.0, 200.0), ylim=(200.0, 1000.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3));\nadd_box!(Phases, Temp, Grid; xlim=(-1000.0,-650.0), ylim=(200.0, 1000.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3,MORside=\"right\"));","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Subducting parts of the oceanic plate","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"The starting thermal age at the trench is that of the horizontal part of the oceanic plate (which is different along-trench, given that we have 3 mid oceanic ridge segments!): We want to add a smooth transition from a halfspace cooling 1D thermal profile to a slab that is heated by the surrounding mantle below a decoupling depth d_decoupling.","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"AgeTrench_Myrs = 1000*1e3/(v_spread_cm_yr/1e2)/1e6 #plate age @ trench\ntrench1 = Trench(Start=(200.0,-1000.0), End=(200.0,-400.0), Thickness=90.0, θ_max=45.0, Length=600, Lb=200, WeakzoneThickness=15, WeakzonePhase=7, d_decoupling=175);\nT_slab = LinearWeightedTemperature( F1=HalfspaceCoolingTemp(Age=AgeTrench_Myrs), F2=McKenzie_subducting_slab(Tsurface=0,v_cm_yr=v_spread_cm_yr, Adiabat = 0.0))\nadd_slab!(Phases, Temp, Grid, trench1, phase = lith, T=T_slab);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"AgeTrench_Myrs = (900)*1e3/(v_spread_cm_yr/1e2)/1e6 #plate age @ trench\ntrench1 = Trench(Start=(200.0,-400.0), End=(200.0,200.0), Thickness=90.0, θ_max=45.0, Length=600, Lb=200, WeakzoneThickness=15, WeakzonePhase=7, d_decoupling=175);\nT_slab = LinearWeightedTemperature( F1=HalfspaceCoolingTemp(Age=AgeTrench_Myrs), F2=McKenzie_subducting_slab(Tsurface=0,v_cm_yr=v_spread_cm_yr, Adiabat = 0.0))\nadd_slab!(Phases, Temp, Grid, trench1, phase = lith, T=T_slab);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"AgeTrench_Myrs = 850e3/(v_spread_cm_yr/1e2)/1e6 #plate age @ trench\ntrench1 = Trench(Start=(200.0,200.0), End=(200.0,1000.0), Thickness=90.0, θ_max=45.0, Length=600, Lb=200, WeakzoneThickness=15, WeakzonePhase=7, d_decoupling=175);\nT_slab = LinearWeightedTemperature( F1=HalfspaceCoolingTemp(Age=AgeTrench_Myrs), F2=McKenzie_subducting_slab(Tsurface=0,v_cm_yr=v_spread_cm_yr, Adiabat = 0.0))\nadd_slab!(Phases, Temp, Grid, trench1, phase = lith, T=T_slab);","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Finally, it is often nice to see the deformation of the plate when it subducts. A simple way to do that is to put a stripes on top using add_stripes!, which has the same phase as the subducting crust.","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"add_stripes!(Phases, Grid; stripAxes = (1,1,0), phase = ConstantPhase(0), stripePhase = ConstantPhase(9), stripeWidth=50, stripeSpacing=200)","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Finally, we can add all this to the CartData dataset:","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Grid = addfield(Grid,(;Phases, Temp))\nwrite_paraview(Grid,\"Grid3D_Ridges\");","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"Saved file: Grid3D_Ridges.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"And the resulting image looks like (Image: Mechanical3D_Tutorial_2)","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"","category":"page"},{"location":"man/Tutorial_NumericalModel_3D/","page":"21 - 3D model setups","title":"21 - 3D model setups","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/tutorial_time_Seismicity/#How-to-create-a-movie-that-shows-the-temporal-evolution-of-seismicity","page":"16 - Create movies","title":"How to create a movie that shows the temporal evolution of seismicity","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#Goal","page":"16 - Create movies","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Earthquake data for the 1983-84 unrest:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7","category":"page"},{"location":"man/tutorial_time_Seismicity/#Steps","page":"16 - Create movies","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#1.-Download-all-data-for-region","page":"16 - Create movies","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"(Image: Tutorial_SeismicTime_1)","category":"page"},{"location":"man/tutorial_time_Seismicity/#2.-Earthquakes-in-movie","page":"16 - Create movies","title":"2. Earthquakes in movie","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Create the folder TemporalSeismicity in the current folder and open the movie with the function movie_paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Dates\njulia> p2 = @__FILE__;\njulia> p2last = findlast(\"/\",p2);\njulia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);\njulia> output_path = string(p3,\"/\");\njulia> movie = movie_paraview(name=string(p3,\"/TemporalSeismicity\"), Initialize=true);\njulia> if isdir(string(p3,\"/TemporalSeismicity\"))==0\n mkdir(string(p3,\"/TemporalSeismicity\"));\n end\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"julia> data = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> l = length(data[:,1]);\njulia> dates = Date.(zeros(l,1))\njulia> for i = 1:l\n df = DateFormat(\"yyyymmdd\");\n t1 = string(\"19\",@sprintf(\"%5.o\", data[i,1]));\n t2 = Date(t1[1:8],df);\n dates[i,1] = t2;\n end\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> dates_num = dates - dates[1];\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"julia> nt = 50;\njulia> dt = Dates.Day(nt);\njulia> t = minimum(dates):dt:maximum(dates);\njulia> for itime = 1:length(t)-1\n name = string(p3,\"/TemporalSeismicity/\", string(itime));\n tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);\n we = WE[tt];\n sn = SN[tt];\n Depth1 = depth[tt];\n DN = dates_num[tt];\n label_time = Dates.value(DN[end]);\n if size(tt,1)>1\n Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));\n movie = write_paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);\n end\n end\njulia>movie_paraview(pvd=movie, Finalize=true)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"This tutorial has created a new TemporalSeismicity.pvd file that can be loaded in Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"(Image: Tutorial_SeismicTime_PVD)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"(Image: Tutorial_SeismicTime_Movie)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"16 - Create movies","title":"16 - Create movies","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/surfaces/#Surfaces","page":"Surfaces","title":"Surfaces","text":"","category":"section"},{"location":"man/surfaces/","page":"Surfaces","title":"Surfaces","text":"We have a number of functions to deal with horizontal surfaces, which are defined as GeoData or CartData structures that have 3 dimensional flat coordinate array. Flat implies that the resolution is n by m by 1, which is required to correctly display them in paraview. The most straightforward surface is the topography (which you can obtain with import_topo). Surfaces can be added and subtracted.","category":"page"},{"location":"man/surfaces/","page":"Surfaces","title":"Surfaces","text":"drape_on_topo\nfit_surface_to_points\nabove_surface\nbelow_surface\ninterpolate_data_surface\nis_surface\nremove_NaN_surface!","category":"page"},{"location":"man/surfaces/#GeophysicalModelGenerator.drape_on_topo","page":"Surfaces","title":"GeophysicalModelGenerator.drape_on_topo","text":"Topo = drape_on_topo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo\n\n\n\n\n\ndrape_on_topo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.fit_surface_to_points","page":"Surfaces","title":"GeophysicalModelGenerator.fit_surface_to_points","text":"surf_new = fit_surface_to_points(surf::GeoData, lon_pt::Vector, lat_pt::Vector, depth_pt::Vector)\n\nThis fits the depth values of the surface surf to the depth value of the closest-by-points in (lon_pt,lat_pt, depth_pt)\n\n\n\n\n\nsurf_new = fit_surface_to_points(surf::CartData, lon_pt::Vector, lat_pt::Vector, depth_pt::Vector)\n\nThis fits the depth values of the surface surf to the depth value of the closest-by-points in (lon_pt,lat_pt, depth_pt)\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.above_surface","page":"Surfaces","title":"GeophysicalModelGenerator.above_surface","text":"Above = above_surface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nabove_surface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2;\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,-40km);\njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = above_surface(Data_set3D, Data_Moho);\n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = above_surface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = above_surface(Data_Cart::Union{Q1Data,CartData}, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = above_surface(Grid::CartGrid, DataSurface_Cart::CartData; above=true, cell=false)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.below_surface","page":"Surfaces","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\nBelow = below_surface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = below_surface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\nBelow = below_surface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = below_surface(Data_Cart::Union{CartData,Q1Data}, DataSurface_Cart::CartData, cell=false)\n\nDetermines if points within the 3D Data_Cart structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.interpolate_data_surface","page":"Surfaces","title":"GeophysicalModelGenerator.interpolate_data_surface","text":"Surf_interp = interpolate_data_surface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf.\n\nExample\n\njulia> Data\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = interpolate_data_surface(Data, surf)\n ParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = interpolate_data_surface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.is_surface","page":"Surfaces","title":"GeophysicalModelGenerator.is_surface","text":"issurf = is_surface(surf::AbstractGeneralGrid)\n\nReturns true if surf is a horizontal 3D surface.\n\n\n\n\n\n","category":"function"},{"location":"man/surfaces/#GeophysicalModelGenerator.remove_NaN_surface!","page":"Surfaces","title":"GeophysicalModelGenerator.remove_NaN_surface!","text":"remove_NaN_surface!(Z::Array,X::Array,Y::Array)\n\nRemoves NaN's from a grid Z by taking the closest points as specified by X and Y.\n\n\n\n\n\n","category":"function"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData, CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data, or combine existing paraview files into a *.pvd paraview collection (that can be used to show a movie)","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"write_paraview\nmovie_paraview\nmake_paraview_collection","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.movie_paraview","page":"Paraview output","title":"GeophysicalModelGenerator.movie_paraview","text":"pvd = movie_paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the write_paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = movie_paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = write_paraview(Data, name, pvd=movie, time=itime)\nend\nmovie_paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"function"},{"location":"man/license/","page":"License","title":"License","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/LICENSE.md\"","category":"page"},{"location":"man/license/#license","page":"License","title":"License","text":"","category":"section"},{"location":"man/license/","page":"License","title":"License","text":"MIT LicenseCopyright (c) 2021 Boris Kaus, Marcel Thielmann and Authors (see Authors)Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/#Simple-model-of-a-magmatic-chamber-with-a-volcano-on-top","page":"22 - 3D model setups","title":"Simple model of a magmatic chamber with a volcano on top","text":"","category":"section"},{"location":"man/Tutorial_VolcanoModel_3D/#Aim","page":"22 - 3D model setups","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"The aim of this tutorial is to show you how to create 3D numerical model setups that can be used as initial setups for other codes.","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/#Generating-the-model","page":"22 - 3D model setups","title":"Generating the model","text":"","category":"section"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Lets start with creating a 3D model setup in cartesian coordinates, which uses the CartData data structure, with a resolution of $ 128 \\times 128 \\times 128 $ grid points, inside the domain Omega in -100100 times -100100 times -11050 km","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"using GeophysicalModelGenerator\n\nnx,ny,nz = 128, 128, 128 \nx = range(-100, 100, nx);\ny = range(-100, 100, ny);\nz = range(-110, 50, nz);\nGrid = CartData(xyz_grid(x,y,z));","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Now we create an integer array that will hold the Phases information (which usually refers to the material or rock type in the simulation)","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Phases = fill(0, nx, ny, nz);","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"And as in the previous tutorials we initialize the temperature field:","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Temp = fill(1350.0, nx,ny,nz);","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"For simplicity, we will assume a model with thee horizontal layers with different rheology where later we add the volcano and the magmatic chamber. We use add_box! to generate the initial horizontally layered model:","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"lith = LithosphericPhases(Layers=[15 45 100], Phases=[1 2 3])\nadd_box!(Phases, Temp, Grid; \n xlim=(-100, 100), \n ylim=(-400, 400.0), \n zlim=(-110.0, 0.0), \n phase = lith, \n T = HalfspaceCoolingTemp(Age=20)\n)","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Then we can add the volcanic shape using add_volcano! function. In this case the base of the volcano will be centered at x_i = (000), with a height of 10 km and a 15 km radius:","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"add_volcano!(Phases, Temp, Grid;\n volcanic_phase = 1,\n center = (0, 0, 0),\n height = 10,\n radius = 15,\n base = 0.0,\n background = nothing,\n T = HalfspaceCoolingTemp(Age=20)\n)","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"We can also add a magmatic chamber located below the volcano","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"add_ellipsoid!(Phases, Temp, Grid; \n cen = (0, 0, -40), \n axes = (10, 10, 10),\n phase = ConstantPhase(4),\n)","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"where we prescribe a constant temperature of T=1400^circC","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"@. Temp[Phases == 4] = 1400 \nGrid = addfield(Grid, (;Phases, Temp))","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"Finally we setup the temperature of the air to T^textair=0^circC","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"@. Temp[Phases == 0] = 0 ","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"write_paraview(Grid,\"VolcanoModel3D\");","category":"page"},{"location":"man/Tutorial_VolcanoModel_3D/","page":"22 - 3D model setups","title":"22 - 3D model setups","text":"And the resulting image looks like (Image: Mechanical3D_Tutorial_2)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"EditURL = \"../../../tutorials/Tutorial_Votemaps.jl\"","category":"page"},{"location":"man/Tutorial_Votemaps/#Votemaps","page":"13 - VoteMaps","title":"Votemaps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#Aim","page":"13 - VoteMaps","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.","category":"page"},{"location":"man/Tutorial_Votemaps/#Steps","page":"13 - VoteMaps","title":"Steps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#1.-Load-data","page":"13 - VoteMaps","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to https://seafile.rlp.net/d/22b0fb85550240758552/","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"using JLD2, GeophysicalModelGenerator\n\nPwave_Zhao = load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\")\nPSwave_Koulakov = load(\"Koulakov_Europe.jld2\",\"DataKoulakov_Alps\")\nPwave_Paffrath = load(\"Paffrath_Pwave.jld2\",\"Data_set_Paffrath2021_Vp\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"Pwave_Paffrath\nGeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 km : 31.0385 km]\n fields: (:dVp_Percentage, :Vp, :Resolution)\n\nPSwave_Koulakov\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)","category":"page"},{"location":"man/Tutorial_Votemaps/#2.-Creating-a-votemap","page":"13 - VoteMaps","title":"2. Creating a votemap","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"The idea of Votemaps is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)\nEverything that fulfills this criteria gets the number 1, everything else 0.\nDo the same with other tomographic models (using the same criteria or a different one).\nMake sure that all tomographic models are interpolated to the same grid.\nSum up the 3 models.\nThe resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"So how do we create Votemaps? Doing this is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"Data_VoteMap = votemap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"], dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"GeoData\n size : (100, 100, 100)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -606.0385 km : -10.0 km]\n fields: (:votemap,)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"write_paraview(Data_VoteMap, \"VoteMap_Alps\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"In paraview, this gives (Image: Tutorial_VoteMap)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"Data_VoteMap = votemap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_Percentage>3.0\", \"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"],\n dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"13 - VoteMaps","title":"13 - VoteMaps","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/projection/#Projecting-and-converting-data","page":"Projection","title":"Projecting & converting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.","category":"page"},{"location":"man/projection/#1.-Converting","page":"Projection","title":"1. Converting","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Converting from one coordinate system to the other is straightforward. Let's use Europe as an example:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = import_topo(lon = [-10, 45], lat=[25, 50], file=\"@earth_relief_20m\")\nGeoData\n size : (165, 75, 1)\n lon ϵ [ -10.0 : 44.666666666666664]\n lat ϵ [ 25.0 : 49.666666666666664]\n depth ϵ [ -4.9855 km : 3.123 km]\n fields: (:Topography,)\njulia> write_paraview(Topo,\"Topo\")\nSaved file: Topo.vts","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"The result is shown on the globe as: (Image: Topo_Europe_GeoData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can convert this to UTM zone as:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert(UTMData, Topo)\nUTMData\n UTM zone : 29-38 North\n size : (165, 75, 1)\n EW ϵ [ 197181.31221507967 : 769155.4572884373]\n NS ϵ [ 2.7649477474783654e6 : 5.505892073781423e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> p=ProjectionPoint(Lon=17.3, Lat=37.5)\nProjectionPoint(37.5, 17.3, 703311.4380385976, 4.152826288024972e6, 33, true)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Projecting the GeoData set using this projection point is done with:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert2UTMzone(Topo,p)\nUTMData\n UTM zone : 33-33 North\n size : (165, 75, 1)\n EW ϵ [ -2.0750691599137965e6 : 3.581351293385453e6]\n NS ϵ [ 2.7649477474783654e6 : 5.938114212160672e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is now in UTM Data (in meters), it is distorted. (Image: Topo_Europe_UTMData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Often it is more convenient to have this in CartData, which is done in a similar manner:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart = convert2CartData(Topo,p)\nCartData\n size : (165, 75, 1)\n x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]\n y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]\n z ϵ [ -4.9855 km : 3.123 km]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"This shows that the model is ~5600 by 3000 km. (Image: Topo_Europe_CartData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.","category":"page"},{"location":"man/projection/#2.-Projecting-data","page":"Projection","title":"2. Projecting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"For use with LaMEM, you would need an orthogonal cartesian grid. From the last command above we get some idea on the area, so we can create this:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = CartData(xyz_grid(-2000:20:2000,-1000:20:1000,0))\nCartData\n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Next, we can project the topographic data (in GeoData format) on this orthogonal grid","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = project_CartData(Topo_Cart_orth, Topo, p)\nCartData\n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ -4.485650671162607 km : 2.5909655318121865 km]\n fields : (:Topography,)\njulia> write_paraview(Topo_Cart_orth,\"Topo_Cart_orth\");","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"(Image: Topo_Europe_CartData_Proj) So this interpolates the topographic data from the GeoData to the orthogonal cartesian grid (which can be used with LaMEM, for example).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can do similar projections with full 3D data sets or pointwise data.","category":"page"},{"location":"man/projection/#3.-List-of-relevant-functions","page":"Projection","title":"3. List of relevant functions","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"GeophysicalModelGenerator.convert2CartData\nGeophysicalModelGenerator.project_CartData\nGeophysicalModelGenerator.convert2UTMzone","category":"page"},{"location":"man/projection/#GeophysicalModelGenerator.convert2CartData","page":"Projection","title":"GeophysicalModelGenerator.convert2CartData","text":"convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\nconvert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.project_CartData","page":"Projection","title":"GeophysicalModelGenerator.project_CartData","text":"d_cart = project_CartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = project_CartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = project_CartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.convert2UTMzone","page":"Projection","title":"GeophysicalModelGenerator.convert2UTMzone","text":"convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\nconvert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#Numerical-model-setups","page":"Numerical model setups","title":"Numerical model setups","text":"","category":"section"},{"location":"man/geodynamic_setups/","page":"Numerical model setups","title":"Numerical model setups","text":"In order to generate numerical simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create setups. ","category":"page"},{"location":"man/geodynamic_setups/","page":"Numerical model setups","title":"Numerical model setups","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/geodynamic_setups/","page":"Numerical model setups","title":"Numerical model setups","text":"Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nAdd various geometries (spheres, cuylinders, ellipsoids)\nAdd lithospheric structure\nAdd various 1D thermal structures (and possibilities to combine them)","category":"page"},{"location":"man/geodynamic_setups/","page":"Numerical model setups","title":"Numerical model setups","text":"GeophysicalModelGenerator.add_box!\nGeophysicalModelGenerator.add_layer!\nGeophysicalModelGenerator.add_sphere!\nGeophysicalModelGenerator.add_ellipsoid!\nGeophysicalModelGenerator.add_cylinder!\nGeophysicalModelGenerator.add_stripes!\nGeophysicalModelGenerator.add_slab!\nGeophysicalModelGenerator.make_volc_topo\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.LithosphericTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.compute_phase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.McKenzie_subducting_slab\nGeophysicalModelGenerator.LinearWeightedTemperature","category":"page"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_box!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_box!","text":"add_box!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Tuple = (20,100), [ylim::Tuple = (1,10)], zlim::Tuple = (10,80),\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing,\n cell=false )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (can be any of the grid types in GMG)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\ncell - if true, Phase and Temp are defined on centers\n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = CartData(xyz_grid(-1000:10:1000,0,-660:10:0))\njulia> Phases = zeros(Int32, size(Grid));\njulia> Temp = zeros(Float64, size(Grid));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=HalfspaceCoolingTemp(Age=30))\njulia> Grid = addfield(Grid, (;Phases,Temp)); # Add to Cartesian model\njulia> write_paraview(Grid,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_layer!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_layer!","text":"add_layer!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Tuple = (1,100), [ylim::Tuple = (0,20)], zlim::Tuple = (0,-100),\n phase = ConstantPhase(1),\n T=nothing, cell=false )\n\nAdds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box\nzlim - bottom/top coordinates of box\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExamples\n\nExample 1) Layer with constant phase and temperature\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_sphere!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_sphere!","text":"add_sphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen::Tuple = (0,0,-1), radius::Number,\n phase = ConstantPhase(1).\n T=nothing, cell=false )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with readLaMEMinputfile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_sphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_ellipsoid!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_ellipsoid!","text":"add_ellipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen::Tuple = (-1,-1,-1), axes::Tuple = (0.2,0.1,0.5),\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing, cell=false )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with readLaMEMinputfile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_ellipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_cylinder!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_cylinder!","text":"add_cylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base::Tuple = (-1,-1,-1.5), cap::Tuple = (-1,-1,-0.5), radius::Number,\n phase = ConstantPhase(1),\n T=nothing, cell=false )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with read_LaMEM_inputfile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_cylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_stripes!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_stripes!","text":"add_stripes!(Phase, Grid::AbstractGeneralGrid;\n stripAxes = (1,1,0),\n stripeWidth = 0.2,\n stripeSpacing = 1,\n Origin = nothing,\n StrikeAngle = 0,\n DipAngle = 10,\n phase = ConstantPhase(3),\n stripePhase = ConstantPhase(4),\n cell = false)\n\nAdds stripes to a pre-defined phase (e.g. added using add_box!)\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nGrid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)\nstripAxes - sets the axis for which we want the stripes. Default is (1,1,0) i.e. X, Y and not Z\nstripeWidth - width of the stripe\nstripeSpacing - space between two stripes\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle\nDipAngle - dip angle\nphase - specifies the phase we want to apply stripes to\nstripePhase - specifies the stripe phase\ncell - if true, Phase and Temp are defined on centers\n\nExample\n\nExample: Box with striped phase and constant temperature & a dip angle of 10 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> add_stripes!(Phases, Grid, stripAxes=(1,1,1), stripeWidth=0.2, stripeSpacing=1, Origin=nothing, StrikeAngle=0, DipAngle=10, phase=ConstantPhase(3), stripePhase=ConstantPhase(4))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.add_slab!","page":"Numerical model setups","title":"GeophysicalModelGenerator.add_slab!","text":"add_slab!(Phase, Temp, Grid::AbstractGeneralGrid, trench::Trench; phase = ConstantPhase(1), T = nothing, cell=false)\n\nAdds a curved slab with phase & temperature structure to a 3D model setup.\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (can be any of the grid types in GMG)\ntrench - Trench structure\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\ncell - if true, Phase and Temp are defined on cells\n\nExamples\n\nExample 1) Slab\n\njulia> x = LinRange(0.0,1200.0,128);\njulia> y = LinRange(0.0,1200.0,128);\njulia> z = LinRange(-660,50,128);\njulia> Cart = CartData(xyz_grid(x, y, z));\njulia> Phase = ones(Int64,size(Cart));\njulia> Temp = fill(1350.0,size(Cart));\n# Define the trench:\njulia> trench= Trench(Start = (400.0,400.0), End = (800.0,800.0), θ_max = 45.0, direction = 1.0, n_seg = 50, Length = 600.0, Thickness = 80.0, Lb = 500.0, d_decoupling = 100.0, type_bending =:Ribe)\njulia> phase = LithosphericPhases(Layers=[5 7 88], Phases = [2 3 4], Tlab=nothing)\njulia> TsHC = HalfspaceCoolingTemp(Tsurface=20.0, Tmantle=1350, Age=30, Adiabat=0.4)\njulia> add_slab!(Phase, Temp, Cart, trench, phase = phase, T = TsHC)\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.make_volc_topo","page":"Numerical model setups","title":"GeophysicalModelGenerator.make_volc_topo","text":"makevolctopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by readLaMEMinputfile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = make_volc_topo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = make_volc_topo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> write_paraview(Topo,\"VolcanoTopo\") # Save topography to paraview\nSaved file: VolcanoTopo.vts\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.ConstantTemp","page":"Numerical model setups","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.LinearTemp","page":"Numerical model setups","title":"GeophysicalModelGenerator.LinearTemp","text":"LinearTemp(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"Numerical model setups","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCoolingTemp(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.SpreadingRateTemp","page":"Numerical model setups","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\nNote: the thermal age at the mid oceanic ridge is set to 1 year to avoid division by zero\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.LithosphericTemp","page":"Numerical model setups","title":"GeophysicalModelGenerator.LithosphericTemp","text":"LithosphericTemp(Tsurface=0.0, Tpot=1350.0, dTadi=0.5,\n ubound=\"const\", lbound=\"const, utbf = 50.0e-3, ltbf = 10.0e-3,\n age = 120.0, dtfac = 0.9, nz = 201,\n rheology = example_CLrheology()\n )\n\nCalculates a 1D temperature profile [C] for variable thermal parameters including radiogenic heat source and linearly interpolates the temperature profile onto the box. The thermal parameters are defined in rheology and the structure of the lithosphere is define by LithosphericPhases().\n\nParameters\n\nTsurface : surface temperature [C]\nTpot : potential mantle temperature [C]\ndTadi : adiabatic gradient [K/km]\nubound : Upper thermal boundary condition [\"const\",\"flux\"]\nlbound : Lower thermal boundary condition [\"const\",\"flux\"]\nutbf : Upper thermal heat flux [W/m]; if ubound == \"flux\"\nltbf : Lower thermal heat flux [W/m]; if lbound == \"flux\"\nage : age of the lithosphere [Ma]\ndtfac : Diffusion stability criterion to calculate T_age\nnz : Grid spacing for the 1D profile within the box\nrheology : Structure containing the thermal parameters for each phase [default example_CLrheology]\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.ConstantPhase","page":"Numerical model setups","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.compute_phase","page":"Numerical model setups","title":"GeophysicalModelGenerator.compute_phase","text":"Phase = compute_phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = compute_phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with readLaMEMinputfile)\n\n\n\n\n\n","category":"function"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.LithosphericPhases","page":"Numerical model setups","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 15], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : The thickness of each layer, ordered from top to bottom. The thickness of the last layer does not have to be specified.\nPhases : The phases of the layers, ordered from top to bottom.\nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab are set to Phases[end].\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.McKenzie_subducting_slab","page":"Numerical model setups","title":"GeophysicalModelGenerator.McKenzie_subducting_slab","text":"McKenzie_subducting_slab\n\nThermal structure by McKenzie for a subducted slab that is fully embedded in the mantle.\n\nParameters\n\nTsurface: Top T [C]\nTmantle: Bottom T [C]\nAdiabat: Adiabatic gradient in K/km\nv_cm_yr: Subduction velocity [cm/yr]\nκ: Thermal diffusivity [m2/s]\nit: Number iterations employed in the harmonic summation\n\n\n\n\n\n","category":"type"},{"location":"man/geodynamic_setups/#GeophysicalModelGenerator.LinearWeightedTemperature","page":"Numerical model setups","title":"GeophysicalModelGenerator.LinearWeightedTemperature","text":"LinearWeightedTemperature\n\nStructure that defined a linear average temperature between two temperature fields as a function of distance\n\nParameters\n\nw_min: Minimum weight\nw_max: Maximum weight\ncrit_dist: Critical distance\ndir: Direction of the averaging (:X, :Y or :Z)\nF1: First temperature field\nF2: Second temperature field\n\n\n\n\n\n","category":"type"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"6 - Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"6 - Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"6 - Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#1.-Coast-lines","page":"6 - Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#1.1-Download-land/sea-data","page":"6 - Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#1.2-Save-in-Paraview","page":"6 - Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"julia> Lon,Lat,Depth = lonlatdepth_grid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> write_paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"6 - Coastlines","title":"6 - Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"EditURL = \"../../../tutorials/Tutorial_AlpineData.jl\"","category":"page"},{"location":"man/Tutorial_AlpineData/#Alpine-Data-Visualization","page":"18 - Alpine data integration","title":"Alpine Data Visualization","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/#Goal","page":"18 - Alpine data integration","title":"Goal","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"This is a tutorial to:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Download datasets from known sources\nProcess and unify these datasets with GeophysicalModelGenerator\nSave the resulting dataset\nExport the datasets to Paraview","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"This is a rather lengthy tutorial that combines different other tutorials, but it will guide you through all the steps necessary to obtain a somewhat comprehensive view of the European Alps and their subsurface from a geodynamical point of view.","category":"page"},{"location":"man/Tutorial_AlpineData/#1.-Surface-Topography","page":"18 - Alpine data integration","title":"1. Surface Topography","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"In many cases, we want to add topographic data to our visualization. Here we use GMT.jl to download data from a certain region, and transfer that to GMG. To add the GMT package, simply add it with the julia package manager:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"julia> ]\n(@v1.10) pkg> add GMT","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"and load both GMG and GMT with:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"using GeophysicalModelGenerator, GMT","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"When loading both packages, several GMT routines within GMG will be loaded. One of these routines is the function import_topo, where one simply has to provide the region for which to download the topographic data and the data source.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Topo = import_topo([4,20,37,50], file=\"@earth_relief_01m\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area, as the files become very large.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"If you have issues with loading the topography with GMT, there is also the alternative to download the data yourself and import it using Rasters.jl.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"We can now export this data to a VTK format so that we can visualize it with Paraview. To do so, GMG provides the function write_paraview:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"write_paraview(Topo, \"Topography_Alps\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Also, if you want to save this data for later use in julia, you can save it as *.jld2 file using the function save_GMG:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"save_GMG(\"Topography_Alps\",Topo)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The result looks like: (Image: Alps_Tutorial_1) Note that we used the Oleron scientific colormap from here for the topography.","category":"page"},{"location":"man/Tutorial_AlpineData/#2.-Moho-topography","page":"18 - Alpine data integration","title":"2. Moho topography","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"When looking at data concerning the Alpine subsurface, we are often interested in the depth of the Moho.","category":"page"},{"location":"man/Tutorial_AlpineData/#2.1-Download-and-import-of-the-data","page":"18 - Alpine data integration","title":"2.1 Download and import of the data","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Here, we will use the dataset from Mroczek et al. (2023). This dataset is publicly available and can be downloaded from here. To allow for downloading such data, we use the julia package Downloads.jl, which is a dependency of GMG. To download the Moho data in the current directory, simply type:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"download_data(\"https://datapub.gfz-potsdam.de/download/10.5880.GFZ.2.4.2021.009NUEfb/2021-009_Mroczek-et-al_SWATHD_moho_jul22.csv\",\"MohoMroczek2023.csv\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Here the downloaded file gets the name MohoMroczek2023.dat and will be saved in the current directory. A quick look at the file shows that it contains a header consisting of 11 lines, one line with the description of the different columns and then the actual data. Have a look at the file yourself. To import the CSV file, we will use the package DelimitedFiles.jl. Have a look at its documentation to see the different import options.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"using DelimitedFiles\ndata_mroczek = readdlm(\"MohoMroczek2023.csv\",',',header=false,skipstart=11)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Note that we skipped the first 11 lines of the file as they contain the file header. The result of this operation will look like this:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"julia> data_mroczek = readdlm(\"MohoMroczek2023.csv\",',',header=false,skipstart=11)\n40786×10 Matrix{Any}:\n \"X\" \"Y\" \"Z\" \"lat\" \"lon\" \"depth\" \"tPs\" \"k\" \"interp\" \"tag\"\n 4185.26 1005.66 4640.51 47.152 13.5113 41.54 4.82 1.62 0 \"PA\"\n 4186.9 1005.95 4639.04 47.1319 13.5099 41.4893 4.81 1.62 0 \"PA\"\n 4188.54 1006.24 4637.57 47.1118 13.5085 41.4281 4.8 1.62 0 \"PA\"\n 4190.2 1006.53 4636.11 47.0917 13.5072 41.3568 4.8 1.63 0 \"PA\"\n 4191.86 1006.82 4634.66 47.0716 13.5058 41.2761 4.79 1.63 0 \"PA\"\n 4193.51 1007.12 4633.22 47.0516 13.5045 41.1865 4.78 1.63 0 \"PA\"\n 4195.18 1007.41 4631.78 47.0315 13.5031 41.0887 4.77 1.63 0 \"PA\"\n 4196.85 1007.71 4630.34 47.0114 13.5018 40.9835 4.76 1.63 0 \"PA\"\n 4198.53 1008.01 4628.91 46.9913 13.5004 40.8725 4.75 1.63 0 \"PA\"\n 4183.59 1007.45 4642.47 47.1721 13.5396 40.92 4.75 1.62 0 \"PA\"\n 4185.22 1007.73 4640.99 47.152 13.5382 40.8866 4.75 1.63 0 \"PA\"\n 4186.85 1008.02 4639.51 47.1319 13.5368 40.8435 4.75 1.63 0 \"PA\"\n 4188.49 1008.31 4638.04 47.1118 13.5355 40.7913 4.74 1.63 0 \"PA\"\n 4190.14 1008.6 4636.57 47.0917 13.5341 40.7305 4.73 1.63 0 \"PA\"\n ⋮ ⋮\n 4123.28 1111.52 4669.18 47.5537 15.0867 43.4301 5 1.67 0 \"EU\"\n 4124.02 1111.57 4666.69 47.5336 15.0848 44.7763 5.13 1.67 0 \"EU\"\n 4124.67 1111.59 4664.11 47.5136 15.0828 46.2535 5.28 1.67 0 \"EU\"\n 4125.23 1111.59 4661.42 47.4935 15.0808 47.868 5.44 1.67 0 \"EU\"\n 4125.71 1111.56 4658.63 47.4734 15.0788 49.6226 5.61 1.67 0 \"EU\"\n 4126.09 1111.51 4655.74 47.4533 15.0768 51.5103 5.79 1.66 0 \"EU\"\n 4126.41 1111.45 4652.77 47.4332 15.0749 53.496 6 1.66 0 \"EU\"\n 4126.7 1111.38 4649.78 47.4131 15.0729 55.5207 6.21 1.66 0 \"EU\"\n 4126.93 1111.28 4646.73 47.393 15.0709 57.6306 6.45 1.66 0 \"EU\"\n 4127.05 1111.16 4643.54 47.3729 15.0689 59.9233 6.7 1.66 0 \"EU\"\n 4127.0 1111.0 4640.2 47.3529 15.067 62.4358 6.98 1.66 1 \"EU\"\n 4126.2 1113.34 4649.82 47.4131 15.1 55.4728 6.21 1.66 0 \"EU\"\n 4126.41 1113.24 4646.74 47.393 15.098 57.6211 6.45 1.66 0 \"EU\"\n 4126.5 1113.11 4643.52 47.3729 15.096 59.9569 6.71 1.66 0 \"EU\"","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"We are now only interested in the depth of the Moho at a given longitude/latitude. To obtain these values, we now have to extract columns 4-6. In addition, we also extract the 10th column, as it contains an identifier for the tectonic unit the respective point belongs to.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"lon = zeros(size(data_mroczek,1)-1); lon .= data_mroczek[2:end,5];\nlat = zeros(size(data_mroczek,1)-1); lat .= data_mroczek[2:end,4];\ndepth = zeros(size(data_mroczek,1)-1); depth .= -1.0*data_mroczek[2:end,6]; #multiplied with -1, as we consider depth to be negative\ntag = string.(data_mroczek[2:end,10]); #get unit identifiers und convert them to strings\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"As a next step, we determine how many different tectonic units there are:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"units = unique(tag) #get different units","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"We will use these units later to save the Moho data separately for each tectonic unit.","category":"page"},{"location":"man/Tutorial_AlpineData/#2.2-Converting-the-data-to-a-GMG-dataset","page":"18 - Alpine data integration","title":"2.2 Converting the data to a GMG dataset","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"To convert this data to a GMG dataset, we now have to interpolate it to a regular grid. You can generate the respective grid with the GMG function lonlatdepth_grid","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Lon,Lat,Depth = lonlatdepth_grid(9.9:0.02:15.1,45.0:.02:49.0,0km);\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"To interpolate the Moho data of the different units to this grid, we have here decided to employ a simple Nearest Neighbor interpolation for simplicity.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"using NearestNeighbors","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"!!! note Interpolating data is tricky and may result in unnecessary smoothing of the data. There are different ways to interpolate data on a regular grid. Have a look at our data interpolation tutorial to see the different possibilities.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Now that we have generated the grid, we can loop over our different tectonic units, extract the relevant data points and interpolate them to the regular grid:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"for iunit = 1:length(units)\n Dist = zeros(size(Lon))\n\n #Get all points belonging to the unit\n ind_unit = findall( x -> occursin(units[iunit], x), tag) #index of the points belonging to that unit\n lon_tmp = lon[ind_unit]\n lat_tmp = lat[ind_unit]\n depth_tmp = depth[ind_unit]\n\n #for later checking, we can now save the original point data as a VTK file:\n data_Moho = GeophysicalModelGenerator.GeoData(lon_tmp,lat_tmp,depth_tmp,(MohoDepth=depth_tmp*km,))\n filename = \"Mroczek_Moho_\" * units[iunit]\n write_paraview(data_Moho, filename, PointsData=true)\n\n #Now we create a KDTree for an effective nearest neighbor determination;\n kdtree = KDTree([lon_tmp';lat_tmp']; leafsize = 10)\n points = [Lon[:]';Lat[:]']\n idxs, dists = knn(kdtree, points, 1, true) #get the distance to the nearest data point\n dists = reduce(vcat,dists)\n idxs = reduce(vcat,idxs)\n idxs = reduce(vcat,idxs)\n\n #Having determined the nearest neighbor for each point in our regular grid, we can now directly assign the respective depth. Whenever the nearest neighbor is further than a certain distance away, we assume that there is no Moho at this point and do not assign a depth to that point.\n for i=1:length(idxs)\n if dists[i]<0.02\n Depth[i] = depth_tmp[idxs[i]]*km\n else\n Depth[i] = NaN*km\n end\n Dist[i] = dists[i]\n end\n\n #As we will be using the data later, we would also like to provide some Metadata so that we know where it is coming from:\n Data_attribs = Dict(\n \"author\"=> \"Mroczek et al.\",\n \"year\"=> \"2023\",\n \"doi\"=>\"https://doi.org/10.5880/GFZ.2.4.2021.009\",\n \"url\"=>\"https://nextcloud.gfz-potsdam.de/s/zB5dPNby6X2Kjnj\",\n )\n\n #Finally, we can now export that data to VTK and save a `jld2` file using the `save_GMG` routine\n Data_Moho = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (MohoDepth=Depth,PointDist=Dist),Data_attribs)\n filename = \"Mrozek_Moho_Grid_\" * units[iunit]\n write_paraview(Data_Moho, filename)\n save_GMG(filename,Topo)\n\nend","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Just for checking, we can also plot both the original data and the resulting interpolated Moho: (Image: Alps_Tutorial_2)","category":"page"},{"location":"man/Tutorial_AlpineData/#3.-Seismicity","page":"18 - Alpine data integration","title":"3. Seismicity","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Earthquakes are always interesting, so lets import the seismicity data from ISC.","category":"page"},{"location":"man/Tutorial_AlpineData/#3.1-Download-and-import","page":"18 - Alpine data integration","title":"3.1 Download and import","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"ISC provides a method to download parts of it's catalogue via a web interface. See the description of the interface here. We will now download all reviewed earthquake data between 1990 and 2015 in the same region as the extracted topography. We will only consider earthquakes with a magnitude larger than 3. The resulting dataset is quite large, so consider to either limit the time range or the magnitude range.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"download_data(\"http://www.isc.ac.uk/cgi-bin/web-db-run?request=COLLECTED&req_agcy=ISC-EHB&out_format=QuakeML&ctr_lat=&ctr_lon=&radius=&max_dist_units=deg&searchshape=RECT&top_lat=49&bot_lat=37&left_lon=4&right_lon=20&srn=&grn=&start_year=1990&start_month=1&start_day=01&start_time=00%3A00%3A00&end_year=2015&end_month=12&end_day=31&end_time=00%3A00%3A00&min_dep=&max_dep=&min_mag=3.0&max_mag=&req_mag_type=Any&req_mag_agcy=Any&min_def=&max_def=&prime_only=on&include_magnitudes=on&table_owner=iscehb\",\"ISCData.xml\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Once the data has been downloaded, we can extract lon/lat/depth/magnitude using the GMG function getlonlatdepthmag_QuakeML, which returns a GeoData structure:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Data_ISC = getlonlatdepthmag_QuakeML(\"ISCData.xml\");\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"As before, we can export this dataset to VTK and also save it as a jld2 file (as we are now exporting point data, we have to use the option PointsData=true):","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"write_paraview(Data_ISC, \"EQ_ISC\", PointsData=true);\nsave_GMG(\"EQ_ISC\",Data_ISC)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"(Image: Alps_Tutorial_3)","category":"page"},{"location":"man/Tutorial_AlpineData/#4.-GPS-data","page":"18 - Alpine data integration","title":"4. GPS data","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Besides data on the structure of the subsurface, it is also nice to see the dynamics of a region. Dynamic processes can be nicely seen in the surface velocities given by GPS data. As GPS data consists of three-dimensional vectors, we have to treat it differently than the seismicity data in the previous section. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7.","category":"page"},{"location":"man/Tutorial_AlpineData/#4.1.-Download-and-import-GPS-data:","page":"18 - Alpine data integration","title":"4.1. Download and import GPS data:","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The data related to the paper can be downloaded from: here. There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example, and will therefore download the following data sets:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"download_data(\"https://store.pangaea.de/Publications/Sanchez-etal_2018/ALPS2017_DEF_HZ.GRD\",\"ALPS2017_DEF_HZ.GRD\")\ndownload_data(\"https://store.pangaea.de/Publications/Sanchez-etal_2018/ALPS2017_DEF_VT.GRD\",\"ALPS2017_DEF_VT.GRD\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Next, we will load the data. As above, we will use DelimitedFiles.jl to load the data. Let's first start with the vertical velocities, which are stored in ALPS2017_DEF_VT.GRD. If we open that file with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Column 1: Longitude [degrees] Column 2: Latitude [degrees] Column 3: Velocity in the height direction [m/a] Column 4: Uncertainty of the height component [m/a]","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"data_vz = readdlm(\"ALPS2017_DEF_VT.GRD\",header=false,skipstart=17)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"And extract the data as vectors:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"lon_vz = data_vz[:,1]\nlat_vz = data_vz[:,2]\nvz = data_vz[:,3]","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"To have a closer look at the data, let's plot it. To do so, we will employ the julia package Plots.jl.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"using Plots\nPlots.scatter(lon_vz,lat_vz)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"We can see that the data is distributed on a regular grid. We can determine the size of this grid with:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"nlon = length(unique(lon_vz))\nnlat = length(unique(lat_vz))","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in Paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Lon = zeros(nlon,nlat,1)\nLat = zeros(nlon,nlat,1)\nVz = zeros(nlon,nlat,1)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Lon[:,:,1] = reshape(lon_vz,(nlon,nlat))\nLat[:,:,1] = reshape(lat_vz,(nlon,nlat))\nVz[:,:,1] = reshape(vz,(nlon,nlat))","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Now that we have imported the vertical velocities, let's do the same for the horizontal ones. Again looking at the data, we see that it starts at line 19 and is organized as follows: Column 1: Longitude [degrees] Column 2: Latitude [degrees] Column 3: East component of the deformation [m/a] Column 4: North component of the deformation [m/a] Column 5: Uncertainty of the east component [m/a] Column 6: Uncertainty of the north component [m/a]","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Let's load the data again and extract the relevant data:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"data_vh = readdlm(\"ALPS2017_DEF_HZ.GRD\",header=false,skipstart=18)\n\nlon_vh = data_vh[:,1]\nlat_vh = data_vh[:,2]\nve = data_vh[:,3]\nvn = data_vh[:,4]","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Let's have a look at how the data points of this dataset are distributed:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Plots.scatter(lon_vh,lat_vh)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in regions which are covered with water. This thus requires a bit more work to transfer them to a rectangular grid. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz initialized with NaN (not a number).","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Ve = fill(NaN,size(Vz));\nVn = fill(NaN,size(Vz));\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Next, we loop over all points in lon_Hz,lat_Hz and place them into 2D matrixes:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"for i in eachindex(lon_vh)\n ind = intersect(findall(x->x==lon_vh[i], Lon), findall(x->x==lat_vh[i], Lat))\n Ve[ind] .= ve[i];\n Vn[ind] .= vn[i];\nend","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Vz = Vz*1000;\nVe = Ve*1000;\nVn = Vn*1000;\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"And their magnitude is","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2);\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/#4.2-Interpolate-topography-on-the-grid","page":"18 - Alpine data integration","title":"4.2 Interpolate topography on the grid","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly. Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. As we have already the loaded the topographic map in section 1 of this tutorial, we can simply reuse it. To interpolate, we will use the function interpolate_datafields_2D","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"topo_v, fields_v = interpolate_datafields_2D(Topo, Lon, Lat)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The variable we are interested in is the variable topo_v. fields_v contains the interpolation of all the fields in Topo to the new grid and we only keep it here for completeness. Note that as the topography in the Topo variable is in km, topo_v will also be given the unit of km. Next, we have to combine the data in a GeoData structure. The velocities are specified as a Tuple (called Velocity_mm_year), which is interpreted a vector when saving this to Paraview.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Data_GPS_Sanchez = GeoData(Lon,Lat,topo_v,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topo=fields_v.Topography))","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"And as always, we'll save everything in VTK format and in jld2 format","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"write_paraview(Data_GPS_Sanchez, \"GPS_Sanchez\")\nsave_GMG(\"GPS_Sanchez\",Data_GPS_Sanchez)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"(Image: Alps_Tutorial_4)","category":"page"},{"location":"man/Tutorial_AlpineData/#5.-Seismic-tomography-data","page":"18 - Alpine data integration","title":"5. Seismic tomography data","text":"","category":"section"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Finally, we'd like to have a look at the subsurface by looking at a seismic tomography. To do so, we'll first download the tomography published by Rappisi et al.(2022). The data is provided as NetCDF files:","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"download_data(\"https://figshare.com/ndownloader/files/34093955\",\"aniNEWTON21.nc\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"We can load this file with the NCDatasets package.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"using NCDatasets\ndataset = NCDataset(\"aniNEWTON21.nc\",\"r\")","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The output of this command will also provide you with an overview of the file content. In the following, we will extract some of this content.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"lon = dataset[\"Longitude\"]\nlat = dataset[\"Latitude\"]\ndlnVp = dataset[\"dlnVp\"]\nVp = dataset[\"Vpi\"]\nDepth = dataset[\"Zg\"]","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"As longitude and latitude are only given as 2D grids, we here have to convert them to 3D matrices.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Lon = repeat(lon[:,:],1,1,size(Depth,3));\nLat = repeat(lat[:,:],1,1,size(Depth,3));\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Finally, as we would like to keep the information on the data source, we add this information as a dictionary.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Data_attribs = Dict(\n \"author\"=> \"Rappisi, F. and VanderBeek, B. P. and Faccenda, M. and Morelli, A. and Molinari, I.\",\n \"title\" => \"Slab Geometry and Upper Mantle Flow Patterns in the Central Mediterranean From 3D Anisotropic P-Wave Tomography\",\n \"journal\"=>\"Journal of Geophysical Research: Solid Earth\",\n \"volume\"=>127,\n \"number\"=>5,\n \"pages\"=>\"e2021JB023488\",\n \"doi\"=>\"https://doi.org/10.1029/2021JB023488\",\n \"url\"=>\"https://doi.org/10.1029/2021JB023488\",\n \"year\"=>2022\n)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Now we are all set and can create a GeoData structure which along with metadata","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"Data = GeoData(Lon,Lat,Depth[:,:,:],(Vp=Vp[:,:,:],dVp=dlnVp[:,:,:]),Data_attribs);\nnothing #hide","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"And then we save it again.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"write_paraview(Data, \"Rappisi2022\")\nsave_GMG(\"Rappisi2022\",Data)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"The result looks like: (Image: Alps_Tutorial_5)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"For the sake of this tutorial, we have now imported all the data we would like to look at. All that is missing is now a joint visualization of these datasets. To obtain this visualization, we will load all the VTK files into Paraview and have a look: (Image: Alps_Tutorial_6)","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"A Paraview statefile that reproduces this visualization is available under tutorials/Tutorial_AlpineData.pvsm.","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"","category":"page"},{"location":"man/Tutorial_AlpineData/","page":"18 - Alpine data integration","title":"18 - Alpine data integration","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"EditURL = \"../../../tutorials/Tutorial_Chmy_MPI.jl\"","category":"page"},{"location":"man/Tutorial_Chmy_MPI/#Create-an-initial-model-setup-for-Chmy-and-run-it-in-parallel","page":"Chmy","title":"Create an initial model setup for Chmy and run it in parallel","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/#Aim","page":"Chmy","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"In this tutorial, your will learn how to use Chmy to perform a 2D diffusion simulation on one or multiple CPU's or GPU's. Chmy is a package that allows you to specify grids and fields and create finite difference simulations, by applying stencil-based kernels in an efficient manner.","category":"page"},{"location":"man/Tutorial_Chmy_MPI/#1.-Load-Chmy-and-required-packages","page":"Chmy","title":"1. Load Chmy and required packages","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"using Chmy, Chmy.Architectures, Chmy.Grids, Chmy.Fields, Chmy.BoundaryConditions, Chmy.GridOperators, Chmy.KernelLaunch\nusing KernelAbstractions\nusing Printf\nusing CairoMakie\nusing GeophysicalModelGenerator","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"In case you want to use GPU's, you need to sort out whether you have AMD or NVIDIA GPU's and load the package accordingly: using AMDGPU AMDGPU.allowscalar(false) using CUDA CUDA.allowscalar(false)","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"To run this in parallel you need to load this:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"using Chmy.Distributed\nusing MPI\nMPI.Init()","category":"page"},{"location":"man/Tutorial_Chmy_MPI/#2.-Define-computational-routines","page":"Chmy","title":"2. Define computational routines","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"You need to specify compute kernel for the gradients:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"@kernel inbounds = true function compute_q!(q, C, χ, g::StructuredGrid, O)\n I = @index(Global, NTuple)\n I = I + O\n q.x[I...] = -χ * ∂x(C, g, I...)\n q.y[I...] = -χ * ∂y(C, g, I...)\nend","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"You need to specify a compute kernel to update the concentration","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"@kernel inbounds = true function update_C!(C, q, Δt, g::StructuredGrid, O)\n I = @index(Global, NTuple)\n I = I + O\n C[I...] -= Δt * divg(q, g, I...)\nend","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"And the main function is:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"@views function main(backend=CPU(); nxy_l=(126, 126))\n arch = Arch(backend, MPI.COMM_WORLD, (0, 0))\n topo = topology(arch)\n me = global_rank(topo)\n\n # geometry\n dims_l = nxy_l\n dims_g = dims_l .* dims(topo)\n grid = UniformGrid(arch; origin=(-2, -2), extent=(4, 4), dims=dims_g)\n launch = Launcher(arch, grid, outer_width=(16, 8))\n\n ##@info \"mpi\" me grid\n\n nx, ny = dims_g\n # physics\n χ = 1.0\n # numerics\n Δt = minimum(spacing(grid))^2 / χ / ndims(grid) / 2.1\n # allocate fields\n C = Field(backend, grid, Center())\n P = Field(backend, grid, Center(), Int32) # phases\n\n q = VectorField(backend, grid)\n C_v = (me==0) ? KernelAbstractions.zeros(CPU(), Float64, size(interior(C)) .* dims(topo)) : nothing\n\n # Use the `GeophysicalModelGenerator` to set the initial conditions. Note that\n # you have to call this for a `Phases` and a `Temp` grid, which we call `C` here.\n add_box!(P,C,grid, xlim=(-1.0,1.0), zlim=(-1.0,1.0), phase=ConstantPhase(4), T=ConstantTemp(400))\n\n # set BC's and updates the halo:\n bc!(arch, grid, C => Neumann(); exchange=C)\n\n # visualisation\n fig = Figure(; size=(400, 320))\n ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel=\"x\", ylabel=\"y\", title=\"it = 0\")\n plt = heatmap!(ax, centers(grid)..., interior(C) |> Array; colormap=:turbo)\n Colorbar(fig[1, 2], plt)\n # action\n nt = 100\n for it in 1:nt\n (me==0) && @printf(\"it = %d/%d \\n\", it, nt)\n launch(arch, grid, compute_q! => (q, C, χ, grid))\n launch(arch, grid, update_C! => (C, q, Δt, grid); bc=batch(grid, C => Neumann(); exchange=C))\n end\n KernelAbstractions.synchronize(backend)\n gather!(arch, C_v, C)\n if me == 0\n fig = Figure(; size=(400, 320))\n ax = Axis(fig[1, 1]; aspect=DataAspect(), xlabel=\"x\", ylabel=\"y\", title=\"it = 0\")\n plt = heatmap!(ax, C_v; colormap=:turbo) # how to get the global grid for axes?\n Colorbar(fig[1, 2], plt)\n save(\"out_gather_$nx.png\", fig)\n end\n return\nend","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"In the code above, the part that calls GMG is:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"add_box!(P,C,grid, xlim=(-1.0,1.0), zlim=(-1.0,1.0), phase=ConstantPhase(4), T=ConstantTemp(400))","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"which works just like any of the other GMG function, except that you pass Chmy Scalar Fields and a Chmy grid object. Note that this also works in MPI-parallel.","category":"page"},{"location":"man/Tutorial_Chmy_MPI/#3.-Run-the-simulation-on-one-CPU-machine-or-GPU-card:","page":"Chmy","title":"3. Run the simulation on one CPU machine or GPU card:","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"Running the code on the CPU is done with this:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"n = 128\nmain(; nxy_l=(n, n) .- 2)","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"If you instead want to run this on AMD or NVIDIA GPU's do this:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"# main(ROCBackend(); nxy_l=(n, n) .- 2)\n# main(CUDABackend(); nxy_l=(n, n) .- 2)","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"And we need to finalize the simulation with","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"MPI.Finalize()","category":"page"},{"location":"man/Tutorial_Chmy_MPI/#4.-Run-the-simulation-on-an-MPI-parallel-machine","page":"Chmy","title":"4. Run the simulation on an MPI-parallel machine","text":"","category":"section"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"If you want to run this on multiple cores, you will need to setup the MPI.jl package, such that mpiexecjl is created on the command line.","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"You can than run it with:","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"mpiexecjl -n 4 --project=. julia Tutorial_Chmy_MPI.jl","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"The full file can be downloaded here","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"","category":"page"},{"location":"man/Tutorial_Chmy_MPI/","page":"Chmy","title":"Chmy","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"EditURL = \"../../../tutorials/Tutorial_MohoTopo_Spada.jl\"","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#Moho-Topography","page":"4 - Visualize Moho topography","title":"Moho Topography","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/#Goal","page":"4 - Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file. The data comes from the following publication: Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#1.-Download-data","page":"4 - Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The data is available as digital dataset on the Researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919_Moho_Map_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 separate ascii files and uploaded it.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"We start with loading the necessary packages","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"using DelimitedFiles, GeophysicalModelGenerator","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Please download the files","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\nMoho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\nMoho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"This can be done using download_data:","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"download_data(\"https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/files/?p=%2FMoho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt&dl=1\",\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\")\ndownload_data(\"https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/files/?p=%2FMoho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt&dl=1\",\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\")\ndownload_data(\"https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/files/?p=%2FMoho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt&dl=1\",\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\")","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#2.-Read-data-into-Julia","page":"4 - Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"data = readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\nlon, lat, depth = data[:,1], data[:,2], -data[:,3];\nnothing #hide","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#3.-Reformat-the-data","page":"4 - Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"using Plots\nscatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"(Image: DataPoints) What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"using GeophysicalModelGenerator\ndata_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"GeoData\n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"write_paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"data = readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\nlon, lat, depth = data[:,1], data[:,2], -data[:,3];\ndata_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nwrite_paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true)\ndata =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\nlon, lat, depth = data[:,1], data[:,2], -data[:,3];\ndata_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nwrite_paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#4.-Fitting-a-mesh-through-the-data","page":"4 - Visualize Moho topography","title":"4. Fitting a mesh through the data","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\nlat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\ndepth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\ndata_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Next, we define a regular lon/lat grid","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Lon, Lat, Depth = lonlatdepth_grid(4.1:0.1:11.9,42.5:.1:49,-30km)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"We will use a nearest neighbor interpolation method to fit a surface through the data, which has the advantage that it will take the discontinuities into account. This can be done with nearest_point_indices","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"idx = nearest_point_indices(Lon,Lat, lon[:],lat[:])\nDepth = depth[idx]","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\nwrite_paraview(data_Moho, \"Spada_Moho_combined\")","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/#5.-Julia-script","page":"4 - Visualize Moho topography","title":"5. Julia script","text":"","category":"section"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"The full julia script that does it all is given here.","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"","category":"page"},{"location":"man/Tutorial_MohoTopo_Spada/","page":"4 - Visualize Moho topography","title":"4 - Visualize Moho topography","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/contributing/","page":"Contributing","title":"Contributing","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/CONTRIBUTING.md\"","category":"page"},{"location":"man/contributing/#contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"man/contributing/","page":"Contributing","title":"Contributing","text":"ContributingGeophysicalModelGenerator.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact with one of the principal developers first (see Authors).GeophysicalModelGenerator.jl and its contributions are licensed under the MIT license. As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.Developer Certificate of Origin (Version 1.1)The following text was taken from https://developercertificate.org:Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Letterman Drive\nSuite D4700\nSan Francisco, CA, 94129\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.","category":"page"},{"location":"man/tutorial_local_Flegrei/#Campi-Flegrei-Volcano-tutorial-using-cartesian-coordinates","page":"14 - Campi Flegrei","title":"Campi Flegrei Volcano tutorial using cartesian coordinates","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#Goal","page":"14 - Campi Flegrei","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Two shape files containing coastline and faults:\nVilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508\nEarthquake data for two volcanic unrests, in 1983-84 and 2005-2016:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7\nDe Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817\nTravel time tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x\nAmbient noise tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x","category":"page"},{"location":"man/tutorial_local_Flegrei/#Steps","page":"14 - Campi Flegrei","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#1.-Download-all-data-for-region","page":"14 - Campi Flegrei","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Make sure that you are in the unzipped directory.","category":"page"},{"location":"man/tutorial_local_Flegrei/#2.-Geomorphology","page":"14 - Campi Flegrei","title":"2. Geomorphology","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Load both the the shape (.shp) files contained in ./Geomorphology/*.shp inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_Geomorphology)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates","category":"page"},{"location":"man/tutorial_local_Flegrei/#3.-Earthquakes","page":"14 - Campi Flegrei","title":"3. Earthquakes","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Now let's plot earthquake data provided as text files. Start loading the data contained in ./SeismicLocations/*.txt. The first column gives us a temporal marker we can use to plot earthquakes in different periods.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Glob, GeoStats\njulia> data_80s = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> data_00s = readdlm(\"SeismicLocations/Seismicity_UTM_2005_2016.txt\", ' ', skipstart=0, header=false);\njulia> data = vcat(data_80s,data_00s) \njulia> time = data[:,1];\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> EQ_Data_Cart = CartData(WE,SN,depth,(Depth=depth * m,Time=time * yr,));\njulia> write_paraview(EQ_Data_Cart, \"CF_Earthquakes_Cartesian\", PointsData=true)\njulia> EQ_Data_UTM = UTMData(WE, SN, depth, 33, true, (Depth=depth * m,Time=time * yr,));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,EQ_Data_UTM)\njulia> write_paraview(Data_set_UTM, \"CF_Earthquakes_UTM\", PointsData=true)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Save in paraview with both cartesian and UTM formats. The final seismicity map looks like this:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_seismicity)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"The colour scale distinguishes earthquakes of different decades. Notice the progressive migration of recent seismicity (black dots) towards East.","category":"page"},{"location":"man/tutorial_local_Flegrei/#4.-Velocity-model","page":"14 - Campi Flegrei","title":"4. Velocity model","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in ./TravelTmeTomography/modvPS.dat for both cartesian and UTM coordinates.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"TravelTimeTomography/modvPS.dat\", '\\t', Float64, skipstart=0, header=false);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vp = data[:,4];\njulia> Vs = data[:,5];\njulia> VpVs = data[:,6];\njulia> resolution = (length(unique(depth)), length(unique(SN)), length(unique(WE)))\njulia> dim_perm = [3 2 1]\njulia> we = permutedims(reshape(WE, resolution), dim_perm);\njulia> sn = permutedims(reshape(SN, resolution), dim_perm);\njulia> depth = permutedims(reshape(depth, resolution), dim_perm);\njulia> Vp3d = permutedims(reshape(Vp, resolution), dim_perm);\njulia> Vs3d = permutedims(reshape(Vs, resolution), dim_perm);\njulia> Vp_Vs3d = permutedims(reshape(VpVs, resolution), dim_perm);\njulia> Data_set_Cartesian = CartData(we, sn, depth, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> write_paraview(Data_set_Cartesian, \"CF_Velocity_Cartesian\")\njulia> Data_set = UTMData(we, sn, depth, 33, true, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,Data_set)\njulia> write_paraview(Data_set_UTM, \"CF_Velocity_UTM\")","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Including the Vp/Vs model in the previous Paraview file workspace:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_VpVs)","category":"page"},{"location":"man/tutorial_local_Flegrei/#5.-Horizontal-slices-of-shear-velocity-on-irregular-grid","page":"14 - Campi Flegrei","title":"5. Horizontal slices of shear velocity on irregular grid","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files ./NoiseTomography/*.txt. We read them consecutively in a \"for\" loop:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"julia> list_files = glob(\"AmbientNoiseTomography/*.txt\");\njulia> li = size(list_files, 1);\njulia> for i = 1:li\n nameFile = list_files[i];\n name_vts = name_vts[24:26];\n data = readdlm(nameFile, '\\t', Float64);\n WE = data[:,1];\n SN = data[:,2];\n depth = data[:,3];\n Vs = data[:,4];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"However these models are too wide, so it is better to constrain them:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":" findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );\n WE = WE[ind];\n SN = SN[ind];\n depth = depth[ind];\n Vs = Vs[ind];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"Also, nodes are irregular, hence we create a 3D regular UTM:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":" l = length(WE);\n n_WE = minimum(WE):100:maximum(WE);\n n_SN = minimum(SN):100:maximum(SN);\n we, sn, Depth = xyz_grid(n_WE, n_SN, depth[1]);\n Vs_3D = zeros(size(Depth));\n Cgrid = GeoStats.CartesianGrid((size(we, 1), size(we, 2)), (minimum(we), minimum(sn)), (we[2,2,1] - we[1,1,1], sn[2,2,1] - sn[1,1,1]))\n coord = PointSet([WE[:]'; SN[:]']);\n Geo = georef((Vs = Vs[:],), coord);\n P = EstimationProblem(Geo, Cgrid, :Vs);\n S = IDW(:Vs => (;neighbors=2));\n sol = solve(P, S);\n sol_Vs = values(sol).Vs;\n Vs_2D = reshape(sol_Vs, size(domain(sol)));\n Vs_3D[:,:,1] = Vs_2D;\n Data_set_Cart = CartData(we, sn, Depth, (Vs = Vs_3D * (km / s),))\n write_paraview(Data_set_Cart, \"CF_Noise\" * name_vts * \"_Cartesian\")\n Data_set = UTMData(we, sn, Depth, 33, true, (Vs = Vs_3D*(km / s),));\n Data_set_UTM = convert(GeophysicalModelGenerator.GeoData, Data_set);\n write_paraview(Data_set_UTM, \"CF_Noise_UTM_\"*name_vts)\n end","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"This is one of the horizontal sections created by the code in the previous model in both reference systems:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_Noise)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"14 - Campi Flegrei","title":"14 - Campi Flegrei","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"EditURL = \"../../../tutorials/Tutorial_NumericalModel_2D.jl\"","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Creating-2D-numerical-model-setups","page":"20 - 2D model setups","title":"Creating 2D numerical model setups","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/#Aim","page":"20 - 2D model setups","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The aim of this tutorial is to show you how to create 2D numerical model setups that can be used as initial setups for other codes.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#2D-Subduction-setup","page":"20 - 2D model setups","title":"2D Subduction setup","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Lets start with creating a 2D model setup in cartesian coordinates, which uses the CartData data structure","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"using GeophysicalModelGenerator\n\nnx,nz = 512,128\nx = range(-1000,1000, nx);\nz = range(-660,0, nz);\nGrid2D = CartData(xyz_grid(x,0,z))","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"CartData \n size : (512, 1, 128)\n x ϵ [ -1000.0 : 1000.0]\n y ϵ [ 0.0 : 0.0]\n z ϵ [ -660.0 : 0.0]\n fields : (:Z,)\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Now we create an integer array that will hold the Phases information (which usually refers to the material or rock type in the simulation)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Phases = zeros(Int64, nx, 1, nz);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"In many (geodynamic) models, one also has to define the temperature, so lets initiate it","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Temp = fill(1350.0, nx, 1, nz);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Mechanical-setup","page":"20 - 2D model setups","title":"Mechanical setup","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"We will start with a simple subduction setup, which consists of a horizontal part:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"add_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = ConstantPhase(1));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"And with the inclined part:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"add_box!(Phases, Temp, Grid2D; xlim=(0.0,300.0), zlim=(-80.0, 0.0), phase = ConstantPhase(1), DipAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Add them to the CartData dataset:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Grid2D = addfield(Grid2D,(;Phases, Temp))","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"CartData \n size : (512, 1, 128)\n x ϵ [ -1000.0 : 1000.0]\n y ϵ [ 0.0 : 0.0]\n z ϵ [ -660.0 : 0.0]\n fields : (:Z, :Phases, :Temp)\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Which looks like","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"write_paraview(Grid2D,\"Grid2D_SubductionMechanical\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionMechanical.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_1)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Add-lithospheric-layers","page":"20 - 2D model setups","title":"Add lithospheric layers","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"In many geodynamic models, the lithosphere consists of a crust and mantle (or upper crust, lower crust and mantle lithosphere). We can use the function LithosphericPhases for this, which is a simple way to set a lithospheric layering. The layering here is defined by the Layers and Phases arguments, where Layers is a vector of the thickness of each of the layers (counting from the top) and Phases is a vector of the phase numbers for each layer.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"lith = LithosphericPhases(Layers=[15 55], Phases=[1 2])","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"LithosphericPhases([15 55], [1 2], nothing)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"and set the slab again:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"add_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = lith);\nadd_box!(Phases, Temp, Grid2D; xlim=(0.0,300.0), zlim=(-80.0, 0.0), phase = lith, DipAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Which looks like:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Grid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionMechanicalLayered\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionMechanicalLayered.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_2)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Add-halfspace-cooling-thermal-structure","page":"20 - 2D model setups","title":"Add halfspace cooling thermal structure","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"So far, we only created the mechanical structure but not the thermal one. We can do that by specifying a thermal structure. For example, we can use the half-space cooling model:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"therm = HalfspaceCoolingTemp(Age=40)\nadd_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = lith, T=therm);\nadd_box!(Phases, Temp, Grid2D; xlim=(0.0,300.0), zlim=(-80.0, 0.0), phase = lith, T = therm, DipAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Which looks like:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Grid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionHalfspaceCooling\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionHalfspaceCooling.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_3)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Note that you can specify other 1D thermal profiles, such as","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"ConstantTemp\nLinearTemp\nHalfspaceCoolingTemp\nLithosphericTemp - which takes radioactive heating into account\nSpreadingRateTemp - which assumes that the plate moved away from a ridge and the thermal age increased accordingly\nMcKenzie_subducting_slab - temperature of a slab that is heated by surrounding mantle","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"You can also average 1D profiles:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"LinearWeightedTemperature - Average 2 1D profiles along a distance","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Add-a-ridge","page":"20 - 2D model setups","title":"Add a ridge","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Let's specify an oceanic thermal profile with a mid oceanic ridge at the left. For this, we use the SpreadingRateTemp function, and specify a spreading velocity (note that this simply relates to the thermal structure and does not have to be the same as the subduction velocity you obtain in your geodynamic simulation).","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"lith = LithosphericPhases(Layers=[15 55], Phases=[1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"For the subduction we use a thermal structure of a slab heated by hot asthenosphere","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"add_box!(Phases, Temp, Grid2D; xlim=(0.0,300.0), zlim=(-80.0, 0.0), phase = lith, T = McKenzie_subducting_slab(Tsurface=0,v_cm_yr=3), DipAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"We can set the mantle lithosphere that is hotter > 1250 C to mantle:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"ind = findall(Temp .> 1250 .&& Phases .==2);\nPhases[ind] .= 0;\n\nGrid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionRidge\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionRidge.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_4)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Overriding-slab-and-weak-layer","page":"20 - 2D model setups","title":"Overriding slab and weak layer","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Ok, lets add an overriding slab as well. For this, we use the add_layer! function","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"lith = LithosphericPhases(Layers=[15 20 55], Phases=[3 4 5], Tlab=1250)\nadd_box!(Phases, Temp, Grid2D; xlim=(0.0,1000.0), zlim=(-80.0, 0.0), phase = lith, T=HalfspaceCoolingTemp(Age=80));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The oceanic plate is as before","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"lith = LithosphericPhases(Layers=[15 55], Phases=[1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=3));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"For the inclined part, we set a layer above the slab (the \"weak\" layer to facilitate subduction initiation )","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"lith = LithosphericPhases(Layers=[10 15 55], Phases=[6 1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid2D; xlim=(0.0,300.0), zlim=(-80.0, 10.0), phase = lith, T = McKenzie_subducting_slab(Tsurface=0,v_cm_yr=3), DipAngle=30);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Lithosphere-asthenosphere boundary:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"ind = findall(Temp .> 1250 .&& Phases .==2);\nPhases[ind] .= 0;\n\nGrid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionOverriding\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionOverriding.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_5)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Curved-slab-mechanics","page":"20 - 2D model setups","title":"Curved slab - mechanics","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"So far, the subducting part of the slab was always straight. We can also create a curved slab by using the add_slab! function. This uses a parametric representation of the slab and is a bit more involved than the add_box! function.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"We start with the horizontal part:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"nx,nz = 512,128\nx = range(-1000,1000, nx);\nz = range(-660,0, nz);\nGrid2D = CartData(xyz_grid(x,0,z))\nPhases = zeros(Int64, nx, 1, nz);\nTemp = fill(1350.0, nx, 1, nz);\nadd_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-80.0, 0.0), phase = ConstantPhase(1));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Next, we should define a Trench structure, which contains info about the trench which goes in 3D from Start - End coordinates (x,y)-coordinates respectively. As we are dealing with a 2D model, we set the y-coordinates to -100.0 and 100.0 respectively. Other parameters to be specified are Thickness (Slab thickness), θ_max (maximum slab dip angle), Length (length of slab), and Lb length of bending zoneof slab","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"trench = Trench(Start=(0.0,-100.0), End=(0.0,100.0), Thickness=80.0, θ_max=45.0, Length=300, Lb=200, direction=-1.0);\nadd_slab!(Phases, Temp, Grid2D, trench, phase = ConstantPhase(1));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Add them to the CartData dataset:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Grid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionCurvedMechanical\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionCurvedMechanical.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"(Image: Mechanical2D_Tutorial_6)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Curved-slab-thermo-mechanics","page":"20 - 2D model setups","title":"Curved slab - thermo-mechanics","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The add_slab! function has a few more interesting options. You can, for example, specify a weak decoupling layer above the slab which adds a weak layer between the subducting and overriding slab. You can also indicate a thermal structure for the slab, which can increase from a halfspace cooling model (of the horizontal part of the slab) to a slab that is heated by the surrounding mantle below a decouping depth d_decoupling.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Our starting basis is the example above with ridge and overriding slab","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"nx,nz = 512,128\nx = range(-1000,1000, nx);\nz = range(-660,0, nz);\nGrid2D = CartData(xyz_grid(x,0,z))\nPhases = zeros(Int64, nx, 1, nz);\nTemp = fill(1350.0, nx, 1, nz);\nlith = LithosphericPhases(Layers=[15 20 55], Phases=[3 4 5], Tlab=1250)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"LithosphericPhases([15 20 55], [3 4 5], 1250)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Lets start with defining the horizontal part of the overriding plate. Note that we define this twice with different thickness to deal with the bending subduction area:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"add_box!(Phases, Temp, Grid2D; xlim=(200.0,1000.0), zlim=(-150.0, 0.0), phase = lith, T=HalfspaceCoolingTemp(Age=80));\nadd_box!(Phases, Temp, Grid2D; xlim=(0.0,200.0), zlim=(-50.0, 0.0), phase = lith, T=HalfspaceCoolingTemp(Age=80));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The horizontal part of the oceanic plate is as before:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"v_spread_cm_yr = 3 #spreading velocity\nlith = LithosphericPhases(Layers=[15 55], Phases=[1 2], Tlab=1250)\nadd_box!(Phases, Temp, Grid2D; xlim=(-800.0,0.0), zlim=(-150.0, 0.0), phase = lith, T=SpreadingRateTemp(SpreadingVel=v_spread_cm_yr));","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Yet, now we add a trench as well. The starting thermal age at the trench is that of the horizontal part of the oceanic plate:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"AgeTrench_Myrs = 800e3/(v_spread_cm_yr/1e2)/1e6 #plate age @ trench","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"26.666666666666668","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"We want to add a smooth transition from a halfspace cooling 1D thermal profile to a slab that is heated by the surrounding mantle below a decoupling depth d_decoupling.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"T_slab = LinearWeightedTemperature( F1=HalfspaceCoolingTemp(Age=AgeTrench_Myrs), F2=McKenzie_subducting_slab(Tsurface=0,v_cm_yr=v_spread_cm_yr, Adiabat = 0.0))","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"LinearWeightedTemperature(0.0, 1.0, 100.0, :X, HalfspaceCoolingTemp(0, 1350, 26.666666666666668, 0), McKenzie_subducting_slab(0.0, 1350.0, 0.0, 3.0, 1.0e-6, 36))","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"in this case, we have a more reasonable slab thickness:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"trench = Trench(Start=(0.0,-100.0), End=(0.0,100.0), Thickness=90.0, θ_max=30.0, Length=600, Lb=200,\n WeakzoneThickness=15, WeakzonePhase=6, d_decoupling=125);\nadd_slab!(Phases, Temp, Grid2D, trench, phase = lith, T=T_slab);","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Lithosphere-asthenosphere boundary:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"ind = findall(Temp .> 1250 .&& (Phases.==2 .|| Phases.==5));\nPhases[ind] .= 0;\n\nGrid2D = addfield(Grid2D,(;Phases, Temp))\nwrite_paraview(Grid2D,\"Grid2D_SubductionCurvedOverriding\");","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Saved file: Grid2D_SubductionCurvedOverriding.vts\n","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The result is a smooth transition in thermal structure around the subduction zone: (Image: Mechanical2D_Tutorial_7)","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/#Other-geometries","page":"20 - 2D model setups","title":"Other geometries","text":"","category":"section"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"We have a number of other functions to help create a geometry, specifically:","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"AddLayer!\nAddSphere!\nAddEllipsoid!\nAddCylinder!","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"The help functions are quite self-explanatory, so we won't show it in detail here. If you have a topography surface or any other horizontal surface, you can surface with the cartesian grid with above_surface or below_surface.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"Also, if you wish to take a seismic tomography as inspiration to set a slab geometry, you can interpolate it to a CartGrid with the same dimensions and use that with the julia findall function.","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"","category":"page"},{"location":"man/Tutorial_NumericalModel_2D/","page":"20 - 2D model setups","title":"20 - 2D model setups","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#3D-tomography-model-in-CSV-formation","page":"2 - 3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"2 - 3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"2 - 3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#1.-Download-data","page":"2 - 3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#2.-Read-data-into-Julia","page":"2 - 3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮\n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#3.-Reformat-the-data","page":"2 - 3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#3.1-Reshape-data-and-save-to-paraview","page":"2 - 3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\nheatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"(Image: DataPoints) So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Next, we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData\n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#4.-Plotting-data-in-Paraview","page":"2 - 3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"In paraview, you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below). In paraview you can open the file and visualize it. (Image: Paraview_1) This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it. (Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section at 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at 3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Note that using geographic coordinates is slightly cumbersome in Paraview. If your area is not too large, it may be advantageous to transfer all data to cartesian coordinates, in which case it is easier to create slices through the model. This is explained in some of the other tutorials.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#5.-Extract-and-plot-cross-sections-of-the-data","page":"2 - 3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the cross_section function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_cross = cross_section(Data_set, Depth_level=-100km)\nGeoData\n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_cross = cross_section(Data_set, Lon_level=10)\nGeoData\n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_cross = cross_section(Data_set, Lon_level=10, Interpolate=true)\nGeoData\n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_cross = cross_section(Data_set, Start=(1.0,39), End=(18,50))\nGeoData\n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: (Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#6.-Extract-a-(3D)-subset-of-the-data","page":"2 - 3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine extract_subvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_subset = extract_subvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData\n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_subset_interp = extract_subvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData\n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> write_paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#7.-Load-and-save-data-to-disk","page":"2 - 3D seismic tomography from ASCII","title":"7. Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. This can be done with the save_GMG function:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> save_GMG(\"Zhao_Pwave\", Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"julia> Data_set_Zhao2016_Vp = load_GMG(\"Zhao_Pwave\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#8.-Julia-script","page":"2 - 3D seismic tomography from ASCII","title":"8. Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"2 - 3D seismic tomography from ASCII","title":"2 - 3D seismic tomography from ASCII","text":"include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates centered around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation. ","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeoData\nCartData\nUTMData\nQ1Data\nFEData\nParaviewData\nlonlatdepth_grid\nxyz_grid\nProjectionPoint","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> Lat = 1.0:3:10.0;\njulia> Lon = 11.0:4:20.0;\njulia> Depth = (-20:5:-10)*km;\njulia> Lon3D,Lat3D,Depth3D = lonlatdepth_grid(Lon, Lat, Depth);\njulia> Lon3D\n3×4×3 Array{Float64, 3}:\n[:, :, 1] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 2] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 3] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\njulia> Lat3D\n 3×4×3 Array{Float64, 3}:\n [:, :, 1] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n\n [:, :, 2] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n\n [:, :, 3] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\njulia> Depth3D\n 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:\n [:, :, 1] =\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n\n [:, :, 2] =\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n\n [:, :, 3] =\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\njulia> Data = zeros(size(Lon3D));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))\nGeoData\n size : (3, 4, 3)\n lon ϵ [ 11.0 : 19.0]\n lat ϵ [ 1.0 : 10.0]\n depth ϵ [ -20.0 km : -10.0 km]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::Any, y::Any, z::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers\n\nx,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nx,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = xyz_grid(x, y, z);\njulia> Data = Z\njulia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nCartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with\n\njulia> write_paraview(Data_set, \"Data_set\")\n1-element Vector{String}:\n \"Data_set.vts\"\n\nIf you wish, you can convert this to UTMData (which will simply convert the )\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData\n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields: (:FakeData, :Data2)\n\nwhich would allow visualizing this in paraview in the usual manner:\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.UTMData","page":"Data Structures","title":"GeophysicalModelGenerator.UTMData","text":"UTMData(EW::Any, NS:Any, depth::GeoUnit, UTMZone::Int, NorthernHemisphere=true, fields::NamedTuple)\n\nData structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.\n\ndepth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> ew = 422123.0:100:433623.0\njulia> ns = 4.514137e6:100:4.523637e6\njulia> depth = -5400:250:600\njulia> EW,NS,Depth = xyz_grid(ew, ns, depth);\njulia> Data = ustrip.(Depth);\njulia> Data_set = UTMData(EW,NS,Depth,33, true, (FakeData=Data,Data2=Data.+1.))\nUTMData\n UTM zone : 33-33 North\n size : (116, 96, 25)\n EW ϵ [ 422123.0 : 433623.0]\n NS ϵ [ 4.514137e6 : 4.523637e6]\n depth ϵ [ -5400.0 m : 600.0 m]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nIf you wish, you can convert this from UTMData to GeoData with\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData\n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nwhich would allow visualizing this in paraview in the usual manner:\n\njulia> write_paraview(Data_set1, \"Data_set1\")\n1-element Vector{String}:\n \"Data_set1.vts\"\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.Q1Data","page":"Data Structures","title":"GeophysicalModelGenerator.Q1Data","text":"Holds a Q1 Finite Element Data set with vertex and cell data. The specified coordinates are the ones of the vertices.\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.FEData","page":"Data Structures","title":"GeophysicalModelGenerator.FEData","text":"FEData{dim, points_per_cell}\n\nStructure that holds Finite Element info with vertex and cell data. Works in 2D/3D for arbitrary elements\n\nParameters\n\nvertices with the points on the mesh (dim x Npoints)\nconnectivity with the connectivity of the mesh (points_per_cell x Ncells)\nfields with the fields on the vertices\ncellfields with the fields of the cells\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.ParaviewData","page":"Data Structures","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),))\njulia> Data_cart = convert(ParaviewData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.lonlatdepth_grid","page":"Data Structures","title":"GeophysicalModelGenerator.lonlatdepth_grid","text":"Lon, Lat, Depth = lonlatdepth_grid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.xyz_grid","page":"Data Structures","title":"GeophysicalModelGenerator.xyz_grid","text":"X,Y,Z = xyz_grid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as lonlatdepth_grid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = xyz_grid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee lonlatdepth_grid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.ProjectionPoint","page":"Data Structures","title":"GeophysicalModelGenerator.ProjectionPoint","text":"struct ProjectionPoint\n Lon :: Float64\n Lat :: Float64\n EW :: Float64\n NS :: Float64\n zone :: Integer\n isnorth :: Bool\nend\n\nStructure that holds the coordinates of a point that is used to project a data set from Lon/Lat to a Cartesian grid and vice-versa.\n\n\n\n\n\n","category":"type"},{"location":"man/authors/#Authors","page":"Authors","title":"Authors","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"GeophysicalModelGenerator.jl's development is coordinated by a group of principal developers, who are also its main contributors and who can be contacted in case of questions about GeophysicalModelGenerator.jl. In addition, there are contributors who have provided substantial additions or modifications. Together, these two groups form \"The GeophysicalModelGenerator.jl Authors\".","category":"page"},{"location":"man/authors/#Principal-Developers","page":"Authors","title":"Principal Developers","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"Boris Kaus, Johannes Gutenberg University Mainz, Germany\nMarcel Thielmann, Bayerisches Geoinstitut, University of Bayreuth, Germany","category":"page"},{"location":"man/authors/#Contributors","page":"Authors","title":"Contributors","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"The following people contributed major additions or modifications to GeophysicalModelGenerator.jl and are listed in alphabetical order:","category":"page"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"Pascal Aellig\nAlbert De Montserrat\nLuca De Siena\nJacob Frasunkiewicz\nLukas Fuchs\nAndrea Piccolo\nHendrik Ranocha\nChristian Schuler\nArne Spang\nTatjana Weiler","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"7 - Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"7 - Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Ideally, all data should be available in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Here, we explain how.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section \\& create VTS file\n3. Read data of a mapview \\& create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"7 - Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#1.-Download-data-and-crop-images","page":"7 - Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#2.-Read-data-of-a-cross-section-and-create-VTS-file","page":"7 - Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"julia> Corner_LowerLeft = ( 4.65, 45.73, -400.0)\njulia> Corner_UpperRight = (17.23, 43.80, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = screenshot_to_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = (4.65 , 45.73 , -400.0 )\n └ lower right = (17.23 , 43.8 , -400.0 )\n └ upper left = (4.65 , 45.73 , 0.0 )\n └ upper right = (17.23 , 43.8 , 0.0 )\nGeoData\n size : (325, 824, 1)\n lon ϵ [ 4.6499999999999995 : 17.230000000000004]\n lat ϵ [ 43.79999999999999 : 45.730000000000004]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"julia> write_paraview(data_profile1, \"Lippitsch_Fig13a_profile\")","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#3.-Read-data-of-a-mapview-and-create-*.vts-file","page":"7 - Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = screenshot_to_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nwrite_paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\")","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#4.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"7 - Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#5.-Creating-a-multiblock-Paraview/*.vtm-file","page":"7 - Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to write_paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> write_paraview(data_Fig12_90km, vtmfile)\njulia> write_paraview(data_Fig12_180km, vtmfile)\njulia> write_paraview(data_Fig12_300km, vtmfile)\njulia> write_paraview(data_Fig12_400km, vtmfile)\njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#6.-Julia-script","page":"7 - Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"7 - Import screenshots","title":"7 - Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"EditURL = \"../../../tutorials/Tutorial_LaPalma.jl\"","category":"page"},{"location":"man/Tutorial_LaPalma/#Create-a-Cartesian-Model-Setup-for-La-Palma","page":"15 - La Palma volcano Model","title":"Create a Cartesian Model Setup for La Palma","text":"","category":"section"},{"location":"man/Tutorial_LaPalma/#Aim","page":"15 - La Palma volcano Model","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"In this tutorial, your will learn how to use real data to create a geodynamic model setup in CartData. We will use the data of the Cumbre Viejo eruption in La Palma, which is a volcanic island that erupted from mid september 2021 - december 2021. The seimsicity from that time-period is used as an inspiration to set the locations of magma intrusions","category":"page"},{"location":"man/Tutorial_LaPalma/#1.-Load-data","page":"15 - La Palma volcano Model","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"We will use two types of data to create the model","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Topography\nEarthquake locations","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"We start with loading the required packages, which includes GMT to download topography (an optional dependency for GeophysicalModelGenerator)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"using GeophysicalModelGenerator, GMT, DelimitedFiles","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"We will use GMT to download the topography with:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Topo = import_topo(lon = [-18.2, -17.5], lat=[28.4, 29.0], file=\"@earth_relief_15s\")","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Next, lets load the seismicity. The earthquake data is available on https://www.ign.es/web/ign/portal/vlc-catalogo. We have filtered them and prepared a file with earthquake locations up to early November 2021 (from january 2021). Download that:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"#download_data(\"https://zenodo.org/records/10738510/files/EQ_events_all_info5_LaPalma_2021.dat\",\"EQ_events_all_info5_LaPalma_2021.dat\")\ndata_EQ = readdlm(\"EQ_events_all_info5_LaPalma_2021.dat\")","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"It has the following format:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"lon = data_EQ[:,1]\nlat = data_EQ[:,2]\ndepth = -data_EQ[:,3]\nMag = data_EQ[:,10]","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Create a GeoData structure from this:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"data_all_EQ = GeoData(lon,lat,depth, (Magnitude=Mag,))","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Next, we can write the data to paraview along with the topography. Note that we have to specify that we have PointData:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"write_paraview(data_all_EQ,\"data_all_EQ\",PointsData=true)\nwrite_paraview(Topo,\"Topo\")","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"(Image: LaPalma_EQTopo_GeoData) Note that this data is in geographic coordinates, which makes it non-trivial to create slices through the data (see coordinate axis in the plot, where z is not pointing upwards).","category":"page"},{"location":"man/Tutorial_LaPalma/#2.-Convert-data-to-cartesian-coordinates","page":"15 - La Palma volcano Model","title":"2. Convert data to cartesian coordinates","text":"","category":"section"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"proj = ProjectionPoint(Lon=-17.84, Lat=28.56)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Once this is done you can convert the topographic data to the cartesian reference frame","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"EQ_cart = convert2CartData(data_all_EQ, proj);\nTopo_cart = convert2CartData(Topo, proj)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Topo_model = CartData(xyz_grid(-35:.1:30,-15:.2:45,0));\nnothing #hide","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"In a next step, the routine project_CartData projects a GeoData structure to a CartData struct","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Topo_model = project_CartData(Topo_model, Topo, proj)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Let's have a look at the data:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"write_paraview(EQ_cart,\"EQ_cart\",PointsData=true)\nwrite_paraview(Topo_model,\"Topo_model\")","category":"page"},{"location":"man/Tutorial_LaPalma/#3.-Create-a-volumetric-earthquake-plot","page":"15 - La Palma volcano Model","title":"3. Create a volumetric earthquake plot","text":"","category":"section"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"It is useful to plot the earthquake density in 3D, which indicates where most action is happening in the system. For this, we first create a 3D grid of the region:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Grid_3D = CartData(xyz_grid(-35:.3:30,-15:.25:45,-50:.5:5))","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Next we check how many earthquakes are around the grid points:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Grid_3D =point_to_nearest_grid(EQ_cart, Grid_3D, radius_factor=3)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"And we can define an array with rock types:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Phases = zeros(Int64,size(Grid_3D.x))","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Points that are below the surface are set to one:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Below = below_surface(Grid_3D, Topo_model);\nPhases[Below] .= 1","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Lets assume that the crust is 15 km thick","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Phases[NumValue(Grid_3D.z) .< -15] .= 2","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"And lets assume that the magma is where we have some earthquake activity:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"ind = findall( (Grid_3D.fields.Count .> 75) .&& Phases.>0)\nPhases[ind] .= 3 #Magma","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Add rocktypes to the grid:","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"Grid_3D = addfield(Grid_3D,\"Phases\",Phases)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"We can save this to paraview format","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"write_paraview(Grid_3D,\"Grid_3D\")","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"The paraview statefile /tutorials/LaPalma.pvsm can be used to reproduce the following plot: (Image: LaPalma_Tutorial)","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"","category":"page"},{"location":"man/Tutorial_LaPalma/","page":"15 - La Palma volcano Model","title":"15 - La Palma volcano Model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/profile_processing/#Profile-processing","page":"Profile Processing","title":"Profile processing","text":"","category":"section"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"We have number of routines that makes it easier to read various datasets into GMG & create profiles through that data The routines provided here have the following functionality:","category":"page"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"Read datasets (remote or local) that contains volumetric, surface, point, topograpy or screenshot data\nDefine a profile (horizontal, vertical) with space for (projected) data\nProject earthquake (point) data onto the profile or intersect surfaces with a vertical profile (e.g., Moho data)","category":"page"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"load_GMG\nsave_GMG\ncross_section\nProfileData\nextract_ProfileData\ncreate_ProfileData\nGMG_Dataset\nload_dataset_file\ncombine_vol_data\nextract_ProfileData!\nread_picked_profiles","category":"page"},{"location":"man/profile_processing/#GeophysicalModelGenerator.load_GMG","page":"Profile Processing","title":"GeophysicalModelGenerator.load_GMG","text":"data::NamedTuple = load_GMG(data::GMG_Dataset)\n\nLoads a dataset specified in GMG_Dataset data and returns it as a named tuple\n\n\n\n\n\nData = load_GMG(Datasets::Vector{GMG_Dataset})\n\nThis loads all the active datasets in Datasets, and returns a NamedTuple with Volume, Surface, Point, Screenshot and Topography data\n\n\n\n\n\nload_GMG(filename::String, dir=pwd(); maxattempts=5)\n\nLoads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it. We make maxattempts attempts to download it before giving up.\n\nExample 1 - Load local file\n\njulia> data = load_GMG(\"test\")\nGeoData \n size : (4, 3, 3)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 19.0]\n depth ϵ [ -20.0 : -10.0]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\nExample 2 - remote download\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\"\njulia> load_GMG(url)\nGeoData \n size : (149, 242, 1)\n lon ϵ [ -24.875 : 35.375]\n lat ϵ [ 34.375 : 71.375]\n depth ϵ [ -11.76 : -34.7]\n fields : (:MohoDepth,)\n attributes: [\"author\", \"year\"]\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.save_GMG","page":"Profile Processing","title":"GeophysicalModelGenerator.save_GMG","text":"save_GMG(filename::String, data::Union{GeoData, CartDat, UTMData}; dir=pwd())\n\nSaves the dataset data to a JLD2 file (name without extension) in the directory dir\n\nExample\n\njulia> Lon3D,Lat3D,Depth3D = lonlatdepth_grid(1.0:3:10.0, 11.0:4:20.0, (-20:5:-10)*km);\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Depth3D,)) \njulia> save_GMG(\"test\",Data_set)\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.cross_section","page":"Profile Processing","title":"GeophysicalModelGenerator.cross_section","text":"cross_section(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)\n\nCreates a cross-section through a GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nDepending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\nVolume data: data will be interpolated or directly extracted from the data set.\nSurface data: surface data will be interpolated or directly extracted from the data set\nPoint data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\nInterpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS\n'section_width' indicates the maximal distance within which point data will be projected to the profile\n\nExample:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = cross_section(Data_set3D, Depth_level=-100km)\nGeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.extract_ProfileData","page":"Profile Processing","title":"GeophysicalModelGenerator.extract_ProfileData","text":"extract_ProfileData(ProfileCoordFile::String,ProfileNumber::Int64,DataSetFile::String; DimsVolCross=(100,100),DepthVol=nothing,DimsSurfCross=(100,),WidthPointProfile=50km)\n\nThis is a convenience function (mostly for backwards compatibility with the MATLAB GUI) that loads the data from file & projects it onto a profile\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.load_dataset_file","page":"Profile Processing","title":"GeophysicalModelGenerator.load_dataset_file","text":"Datasets = load_dataset_file(file_datasets::String)\n\nThis loads a CSV textfile that lists datasets, which is expected to have the following format:\n\nName,Location,Type, [Active]\nAlpArray,./Seismicity/ALPARRAY/AlpArraySeis.jld2,Point, true\nPlomerova2022,https://seafile.rlp.net/f/abccb8d3302b4ef5af17/?dl=1,Volume\n\nNote that the first line of the file is skipped.\n\nHere, the meaning of the variables is:\n\nName: The name of the dataset to be loaded\nLocation: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with \"http\".\nType: type of the dataset (Volume, Surface, Point, Screenshot)\nActive: Do we want this file to be loaded or not? Optional parameter that defaults to true\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.combine_vol_data","page":"Profile Processing","title":"GeophysicalModelGenerator.combine_vol_data","text":"VolData_combined = combine_vol_data(VolData::NamedTuple; lat=nothing, lon=nothing, depth=nothing, dims=(100,100,100), dataset_preferred = 1)\n\nThis takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the \"reference\" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.extract_ProfileData!","page":"Profile Processing","title":"GeophysicalModelGenerator.extract_ProfileData!","text":"extract_ProfileData!(Profile::ProfileData,VolData::GeoData, SurfData::NamedTuple, PointData::NamedTuple; DimsVolCross=(100,100),Depth_extent=nothing,DimsSurfCross=(100,),section_width=50)\n\nExtracts data along a vertical or horizontal profile\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.read_picked_profiles","page":"Profile Processing","title":"GeophysicalModelGenerator.read_picked_profiles","text":"This reads the picked profiles from disk and returns a vector of ProfileData\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"Here an overview of all functions:","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"Modules = [GeophysicalModelGenerator]","category":"page"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{CartGrid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"Data = CartData(Grid::CartGrid, fields::NamedTuple; y_val=0.0)\n\nReturns a CartData set given a cartesian grid Grid and fields defined on that grid.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{LaMEM_grid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"CartData(Grid::LaMEM_grid, fields::NamedTuple)\n\nCreates a CartData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"CartData(xyz::Tuple{Array,Array,Array})\n\nThis creates a CartData struct if you have a Tuple with 3D coordinates as input.\n\nExample\n\njulia> data = CartData(xyz_grid(-10:10,-5:5,0))\nCartData\n size : (21, 11, 1)\n x ϵ [ -10.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartGrid","page":"List of functions","title":"GeophysicalModelGenerator.CartGrid","text":"Structure that holds data for an orthogonal cartesian grid, which can be described with 1D vectors\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GMG_Dataset","page":"List of functions","title":"GeophysicalModelGenerator.GMG_Dataset","text":"Structure that stores info about a GMG Dataset, which is useful to collect a wide variety of datasets.\n\nName :: String # Name of the dataset\nType :: String # Volumetric, Surface, Point, Screenshot\nDirName :: String # Directory name or url of dataset\nactive :: Bool # should this data be loaded or not?\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GeoData-Tuple{Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lld::Tuple{Array,Array,Array})\n\nThis creates a GeoData struct if you have a Tuple with 3D coordinates as input.\n\nExample\n\njulia> data = GeoData(lonlatdepth_grid(-10:10,-5:5,0))\nGeoData \n size : (21, 11, 1)\n lon ϵ [ -10.0 : 10.0]\n lat ϵ [ -5.0 : 5.0]\n depth ϵ [ 0.0 : 0.0]\n fields : (:Z,)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParaviewData-Tuple{LaMEM_grid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(Grid::LaMEM_grid, fields::NamedTuple)\n\nCreates a ParaviewData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProfileData","page":"List of functions","title":"GeophysicalModelGenerator.ProfileData","text":"Structure that holds profile data (interpolated/projected on the profile)\n\nstruct ProfileData\n vertical :: Bool # vertical:true, horizontal:false\n start_lonlat :: Union{Nothing,Tuple{Float64,Float64}}\n end_lonlat :: Union{Nothing,Tuple{Float64,Float64}}\n depth :: Union{Nothing,Float64}\n VolData :: GeophysicalModelGenerator.GeoData\n SurfData :: Union{Nothing, NamedTuple}\n PointData :: Union{Nothing, NamedTuple}\nend\n\nStructure to store cross section data\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectionPoint-Tuple{Float64, Float64, Int64, Bool}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectionPoint","text":"ProjectionPoint(EW::Float64, NS::Float64, Zone::Int64, isnorth::Bool)\n\nDefines a projection point used for map projections, by specifying UTM coordinates (EW/NS), UTM Zone and whether you are on the northern hemisphere\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectionPoint-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectionPoint","text":"ProjectionPoint(; Lat=49.9929, Lon=8.2473)\n\nDefines a projection point used for map projections, by specifying latitude and longitude\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Q1Data-Tuple{Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.Q1Data","text":"Q1Data(xyz::Tuple{Array,Array,Array})\n\nThis creates a Q1Data struct if you have a Tuple with 3D coordinates as input.\n\nExample\n\njulia> data = Q1Data(xyz_grid(-10:10,-5:5,0))\nCartData\n size : (21, 11, 1)\n x ϵ [ -10.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Trench","page":"List of functions","title":"GeophysicalModelGenerator.Trench","text":"Trench structure\n\nStructure that defines the geometry of the trench and the slab.\n\nParameters\n\nStart - Start of the trench (x,y) coordinates\nEnd - End of the trench (x,y) coordinates\nn_seg - The number of segment through which the slab is discretize along the dip\nLength - The length of the slab\nThickness - The thickness of the slab\nLb - Critical distance through which apply the bending angle functions Lb ∈ [0,Length];\nθ_max - maximum angle of bending ∈ [0°,90°].\ndirection - the direction of the dip The rotation of the coordinate system is done as such that the new X is parallel to the segment. Since the rotation is anticlockwise the coordinate y has specific values: direction tells if the subduction is directed along the positive or negative direction of the new y coordinate system. In practice, it apply an additional transformation to y by multiplying it with -1 or +1;\nd_decoupling - depth at which the slab is fully submerged into the mantle.\ntype_bending - is the type of bending angle of the slab [:Linear, :Ribe]. The angle of slab changes as a function of l (∈ [0,Length]). l is the actual distance along the slab length from the trench. In case: - :Linear math θ(l) = ((θ_max - 0.0)/(Lb-0))*l; - :Ribe math θ(l) = θ_max*l^2*((3*Lb-2*l))/(Lb^3); which is taken from Ribe 2010 [Bending mechanics and mode selection in free subduction: a thin-sheet analysis]\nFor l>Lb, θ(l) = θ_max;\nWeakzoneThickness - Thickness of the weakzone [km]\nWeakzonePhase - Phase of the weakzone\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#Base.convert-Tuple{Type{GeoData}, UTMData}","page":"List of functions","title":"Base.convert","text":"Converts a UTMData structure to a GeoData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#Base.convert-Tuple{Type{UTMData}, GeoData}","page":"List of functions","title":"Base.convert","text":"Converts a GeoData structure to a UTMData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Create1D_grid_vector-Tuple{Vector{Float64}, Int64, Int64, Union{Nothing, Int64}, Union{Nothing, Float64}}","page":"List of functions","title":"GeophysicalModelGenerator.Create1D_grid_vector","text":"Returns 1D coordinate vectors of grid points and of marker locations for a regular spacing\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Create1D_grid_vector-Union{Tuple{I}, Tuple{T}, Tuple{Vector{T}, Vector{I}, I, I, Union{Nothing, Vector{T}, T}}} where {T<:Float64, I<:Int64}","page":"List of functions","title":"GeophysicalModelGenerator.Create1D_grid_vector","text":"Returns 1D coordinate vectors of grid points and of marker locations for a regular spacing\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D_vecs-NTuple{6, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D_vecs","text":"InterpolateDataFields2D_vecs(x_vec, y_vec, depth, fields_new, X, Y)\n\nInterpolates a data field V on a 2D grid defined by UTM. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParseValue_CommandLineArgs-NTuple{4, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ParseValue_CommandLineArgs","text":"This parses a LaMEM command line argument string and checks if the keyword exists there\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParseValue_LaMEM_InputFile-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ParseValue_LaMEM_InputFile","text":"value = ParseValue_LaMEM_InputFile(file,keyword,type; args::String=nothing)\n\nExtracts a certain keyword from a LaMEM input file and convert it to a certain type. Optionally, you can also pass command-line arguments which will override the value read from the input file.\n\nExample 1:\n\njulia> nmark_z = ParseValue_LaMEM_InputFile(\"SaltModels.dat\",\"nmark_z\",Int64)\n\nExample 2:\n\njulia> nmark_z = ParseValue_LaMEM_InputFile(\"SaltModels.dat\",\"nmark_z\",Int64, args=\"-nel_x 128 -coord_x -4,4\")\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PetscBinaryWrite_Vec-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.PetscBinaryWrite_Vec","text":"PetscBinaryWrite_Vec(filename, A)\n\nWrites a vector A to disk, such that it can be read with PetscBinaryRead (which assumes a Big Endian type)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Rot3D-Union{Tuple{_T}, NTuple{7, _T}} where _T<:Number","page":"List of functions","title":"GeophysicalModelGenerator.Rot3D","text":"xrot, yrot, zrot = Rot3D(X::Number,Y::Number,Z::Number, cosStrikeAngle, sindStrikeAngle, cosDipAngle, sinDipAngle)\n\nPerform rotation for a point in 3D space\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.above_surface-Tuple{CartGrid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.above_surface","text":"Above = above_surface(Grid::CartGrid, DataSurface_Cart::CartData; above=true, cell=false)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.above_surface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.above_surface","text":"above_surface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2;\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,-40km);\njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = above_surface(Data_set3D, Data_Moho);\n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.above_surface-Tuple{LaMEM_grid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.above_surface","text":"Above = above_surface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.above_surface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.above_surface","text":"Above = above_surface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.above_surface-Tuple{Union{CartData, Q1Data}, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.above_surface","text":"Above = above_surface(Data_Cart::Union{Q1Data,CartData}, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_box!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_box!","text":"add_box!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Tuple = (20,100), [ylim::Tuple = (1,10)], zlim::Tuple = (10,80),\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing,\n cell=false )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (can be any of the grid types in GMG)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\ncell - if true, Phase and Temp are defined on centers\n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = CartData(xyz_grid(-1000:10:1000,0,-660:10:0))\njulia> Phases = zeros(Int32, size(Grid));\njulia> Temp = zeros(Float64, size(Grid));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=HalfspaceCoolingTemp(Age=30))\njulia> Grid = addfield(Grid, (;Phases,Temp)); # Add to Cartesian model\njulia> write_paraview(Grid,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_cylinder!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_cylinder!","text":"add_cylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base::Tuple = (-1,-1,-1.5), cap::Tuple = (-1,-1,-0.5), radius::Number,\n phase = ConstantPhase(1),\n T=nothing, cell=false )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with read_LaMEM_inputfile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_cylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_ellipsoid!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_ellipsoid!","text":"add_ellipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen::Tuple = (-1,-1,-1), axes::Tuple = (0.2,0.1,0.5),\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing, cell=false )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with readLaMEMinputfile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_ellipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_layer!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_layer!","text":"add_layer!(Phase, Temp, Grid::AbstractGeneralGrid; xlim::Tuple = (1,100), [ylim::Tuple = (0,20)], zlim::Tuple = (0,-100),\n phase = ConstantPhase(1),\n T=nothing, cell=false )\n\nAdds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box\nzlim - bottom/top coordinates of box\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExamples\n\nExample 1) Layer with constant phase and temperature\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_layer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_polygon!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_polygon!","text":" add_polygon!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=(), ylim::Tuple = (0.0,0.8), zlim=(), phase = ConstantPhase(1), T=nothing, cell=false )\n\nAdds a polygon with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with readLaMEMinputfile)\nxlim - x-coordinate of the polygon points, same ordering as zlim, number of points unlimited\nylim - y-coordinate, limitation in length possible (two values (start and stop))\nzlim - z-coordinate of the polygon points, same ordering as xlim, number of points unlimited\nphase - specifies the phase of the box. See ConstantPhase()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nPolygon with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_polygon!(Phase, Temp, Cart; xlim=(0,0, 1.6, 2.0),ylim=(0,0.8), zlim=(0,-1,-2,0), phase = ConstantPhase(8), T=ConstantTemp(30))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_slab!-Tuple{Any, Any, AbstractGeneralGrid, Trench}","page":"List of functions","title":"GeophysicalModelGenerator.add_slab!","text":"add_slab!(Phase, Temp, Grid::AbstractGeneralGrid, trench::Trench; phase = ConstantPhase(1), T = nothing, cell=false)\n\nAdds a curved slab with phase & temperature structure to a 3D model setup.\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (can be any of the grid types in GMG)\ntrench - Trench structure\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\ncell - if true, Phase and Temp are defined on cells\n\nExamples\n\nExample 1) Slab\n\njulia> x = LinRange(0.0,1200.0,128);\njulia> y = LinRange(0.0,1200.0,128);\njulia> z = LinRange(-660,50,128);\njulia> Cart = CartData(xyz_grid(x, y, z));\njulia> Phase = ones(Int64,size(Cart));\njulia> Temp = fill(1350.0,size(Cart));\n# Define the trench:\njulia> trench= Trench(Start = (400.0,400.0), End = (800.0,800.0), θ_max = 45.0, direction = 1.0, n_seg = 50, Length = 600.0, Thickness = 80.0, Lb = 500.0, d_decoupling = 100.0, type_bending =:Ribe)\njulia> phase = LithosphericPhases(Layers=[5 7 88], Phases = [2 3 4], Tlab=nothing)\njulia> TsHC = HalfspaceCoolingTemp(Tsurface=20.0, Tmantle=1350, Age=30, Adiabat=0.4)\njulia> add_slab!(Phase, Temp, Cart, trench, phase = phase, T = TsHC)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_sphere!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_sphere!","text":"add_sphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen::Tuple = (0,0,-1), radius::Number,\n phase = ConstantPhase(1).\n T=nothing, cell=false )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with readLaMEMinputfile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\ncell - if true, Phase and Temp are defined on cell centers\n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_sphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_stripes!-Tuple{Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.add_stripes!","text":"add_stripes!(Phase, Grid::AbstractGeneralGrid;\n stripAxes = (1,1,0),\n stripeWidth = 0.2,\n stripeSpacing = 1,\n Origin = nothing,\n StrikeAngle = 0,\n DipAngle = 10,\n phase = ConstantPhase(3),\n stripePhase = ConstantPhase(4),\n cell = false)\n\nAdds stripes to a pre-defined phase (e.g. added using add_box!)\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nGrid - grid structure (usually obtained with readLaMEMinputfile, but can also be other grid types)\nstripAxes - sets the axis for which we want the stripes. Default is (1,1,0) i.e. X, Y and not Z\nstripeWidth - width of the stripe\nstripeSpacing - space between two stripes\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle\nDipAngle - dip angle\nphase - specifies the phase we want to apply stripes to\nstripePhase - specifies the stripe phase\ncell - if true, Phase and Temp are defined on centers\n\nExample\n\nExample: Box with striped phase and constant temperature & a dip angle of 10 degrees:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> add_box!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> add_stripes!(Phases, Grid, stripAxes=(1,1,1), stripeWidth=0.2, stripeSpacing=1, Origin=nothing, StrikeAngle=0, DipAngle=10, phase=ConstantPhase(3), stripePhase=ConstantPhase(4))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> write_paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.add_volcano!-Tuple{Any, Any, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.add_volcano!","text":"addvolcano!( Phases, Temp, Grid::CartData; volcanicphase, center, height, radius, crater, base, background, T, )\n\nAdds a volcano topography (cones and truncated cones)\n\nParameters\n\nPhases - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - CartData\n\nOptional Parameters\n\nvolcanic_phase - phase number of the volcano,\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\nT - temperature structure of the volcano\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.addfield-Tuple{AbstractGeneralGrid, String, Any}","page":"List of functions","title":"GeophysicalModelGenerator.addfield","text":"V = addfield(V::AbstractGeneralGrid,field_name::String,data::Any)\n\nAdd Fields Data to GeoData or CartData\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.addfield-Tuple{CartData, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.addfield","text":"V = addfield(V::CartData,new_fields::NamedTuple)\n\nAdd new_fields fields to a CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.addfield-Tuple{FEData, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.addfield","text":"V = addfield(V::FEData,new_fields::NamedTuple; cellfield=false)\n\nAdd new_fields fields to a FEData dataset; set cellfield to true if the field is a cell field; otherwise it is a vertex field\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.addfield-Tuple{GeoData, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.addfield","text":"V = addfield(V::GeoData,new_fields::NamedTuple)\n\nAdd new_fields fields to a GeoData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.addfield-Tuple{Q1Data, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.addfield","text":"V = addfield(V::Q1Data,new_fields::NamedTuple; cellfield=false)\n\nAdd new_fields fields to a Q1Data dataset; set cellfield to true if the field is a cell field; otherwise it is a vertex field\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.average_q1-Tuple{Array}","page":"List of functions","title":"GeophysicalModelGenerator.average_q1","text":"out = average_q1(d::Array)\n\n3D linear averaging of a 3D array\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.below_surface","page":"List of functions","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Data_Cart::Union{CartData,Q1Data}, DataSurface_Cart::CartData, cell=false)\n\nDetermines if points within the 3D Data_Cart structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.below_surface-Tuple{CartGrid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.below_surface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.below_surface-Tuple{LaMEM_grid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.below_surface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.below_surface","text":"Below = below_surface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cell_area-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.cell_area","text":"area_m2 = cell_area(Topo::GeoData)\n\nReturns the cell area for a Topographic dataset in m² (required for upstream area calculation)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cell_tags_from_gmsh-Tuple{Any}","page":"List of functions","title":"GeophysicalModelGenerator.cell_tags_from_gmsh","text":"tags = cell_tags_from_gmsh(mesh::GmshDiscreteModel)\n\nReturns a list with integers that are the tags for each of the cells\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.combine_vol_data-Tuple{NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.combine_vol_data","text":"VolData_combined = combine_vol_data(VolData::NamedTuple; lat=nothing, lon=nothing, depth=nothing, dims=(100,100,100), dataset_preferred = 1)\n\nThis takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the \"reference\" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.compute_bending_angle-Tuple{Float64, Float64, Float64, Symbol}","page":"List of functions","title":"GeophysicalModelGenerator.compute_bending_angle","text":"θ = compute_bending_angle(θ_max,Lb,l,type)\n\nfunction that computes the bending angle θ as a function of length along the slab l.\n\nParameters\n\nθ_max = maximum bending angle Lb = length at which the function of bending is applied (Lb<=Length) l = current position within the slab type = type of bending [:Ribe,:Linear]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.compute_phase-Tuple{Any, Any, Any, Any, Any, LithosphericPhases}","page":"List of functions","title":"GeophysicalModelGenerator.compute_phase","text":"Phase = compute_phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = compute_phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with readLaMEMinputfile)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.compute_slab_surface-Tuple{Trench}","page":"List of functions","title":"GeophysicalModelGenerator.compute_slab_surface","text":"Top, Bot = compute_slab_surface(trench::Trench)\n\nComputes the (x,z) coordinates of the slab top, bottom surface using the mid surface of the slab as reference.\n\nParameters\n\ntrench - Trench structure that contains the relevant parameters\n\nMethod\n\nIt computes it by discretizing the slab surface in n_seg segments, and computing the average bending angle (which is a function of the current length of the slab). Next, it compute the coordinates assuming that the trench is at 0.0, and assuming a positive θ_max angle.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.compute_thermal_structure-Tuple{Any, Any, Any, Any, Any, LinearWeightedTemperature}","page":"List of functions","title":"GeophysicalModelGenerator.compute_thermal_structure","text":"compute_thermal_structure(Temp, X, Y, Z, Phase, s::LinearWeightedTemperature)\n\nWeight average along distance\n\nDo a weight average between two field along a specified direction\n\nGiven a distance (could be any array, from X,Y) -> the weight of F1 increase from the origin, while F2 decreases.\n\nThis function has been conceived for averaging the solution of McKenzie and half space cooling models, but it can be used to smooth the temperature field from continent ocean:\n\nSelect the boundary to apply;\ntransform the coordinate such that dist represent the perpendicular direction along which you want to apply this smoothening and in a such way that 0.0 is the point in which the weight of F1 is equal to 0.0;\nSelect the points that belongs to this area\ncompute the thermal fields {F1} {F2}\nthen modify F.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.compute_thermal_structure-Tuple{Any, Any, Any, Any, Any, McKenzie_subducting_slab}","page":"List of functions","title":"GeophysicalModelGenerator.compute_thermal_structure","text":"compute_thermal_structure(Temp, X, Y, Z, Phase, s::McKenzie_subducting_slab)\n\nCompute the temperature field of a McKenzie_subducting_slab. Uses the analytical solution of McKenzie (1969) [\"Speculations on the consequences and causes of plate motions\"]. The functions assumes that the bottom of the slab is the coordinate Z=0. Internally the function shifts the coordinate.\n\nParameters\n\n=============================\n\nTemp: Temperature array\nX: X Array\nY: Y Array\nZ: Z Array\nPhase: Phase array\ns: McKenzie_subducting_slab\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.convert2CartData-Tuple{GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.convert2CartData","text":"convert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.convert2CartData-Tuple{UTMData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.convert2CartData","text":"convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.convert2FEData-Tuple{Q1Data}","page":"List of functions","title":"GeophysicalModelGenerator.convert2FEData","text":"fe_data::FEData = convert2FEData(d::Q1Data)\n\nCreates a Q1 FEM mesh from the Q1Data data which holds the vertex coordinates and cell/vertex fields\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.convert2UTMzone-Tuple{CartData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.convert2UTMzone","text":"convert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.convert2UTMzone-Tuple{GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.convert2UTMzone","text":"convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::CartData; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{CartGrid}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::CartGrid; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"LON,LAT,Z = coordinate_grids(Data::GeoData; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{LaMEM_grid}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::LaMEM_grid; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::ParaviewData; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{Q1Data}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::Q1Data; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{UTMData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"EW,NS,Z = coordinate_grids(Data::UTMData; cell=false)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.countmap-Tuple{GeoData, String, Int64, Int64}","page":"List of functions","title":"GeophysicalModelGenerator.countmap","text":"DatasetcountMap = countmap(DataSet::GeoData,field::String,stepslon::Int64,stepslat::Int64)\n\nTakes a 2D GeoData struct and counts entries of field per predefined control area. field should only consist of 1.0s and 0.0s. The control area is defined by steplon and steplat. steplon is the number of control areas in longitude direction and steplat the number of control areas in latitude direction. The counts per control area are normalized by the highest count.\n\njulia> Data_Faults = GeoData(Lon3D,Lat3D,Faults,(Faults=Faults,))\nGeoData \n size : (375, 208, 1)\n lon ϵ [ -9.932408319802885 : 34.93985125012068]\n lat ϵ [ 35.086096468211394 : 59.919210145128545]\n depth ϵ [ 0.0 : 1.0]\n fields : (:Faults,)\n\njulia> steplon = 125\njulia> steplat = 70\njulia> countmap = countmap(Data_Faults,\"Faults\",steplon,steplat)\n\nGeoData \n size : (124, 69, 1)\n lon ϵ [ -9.751471789279 : 34.75891471959677]\n lat ϵ [ 35.26604656731949 : 59.73926004602028]\n depth ϵ [ 0.0 : 1.0]\n fields : (:countmap,)\n\njulia\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.create_CartGrid-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.create_CartGrid","text":"Grid = create_CartGrid(; size=(), x = nothing, z = nothing, y = nothing, extent = nothing, CharDim = nothing)\n\nCreates a 1D, 2D or 3D cartesian grid of given size. Grid can be created by defining the size and either the extent (length) of the grid in all directions, or by defining start & end points (x,y,z). If you specify CharDim (a structure with characteristic dimensions created with GeoParams.jl), we will nondimensionalize the grd before creating the struct.\n\nSpacing is assumed to be constant in a given direction\n\nThis can also be used for staggered grids, as we also create 1D vectors for the central points. The points you indicate in size are the corner points.\n\nNote: since this is mostly for solid Earth geoscience applications, the second dimension is called z (vertical)\n\nExamples\n\n====\n\nA basic case with non-dimensional units:\n\njulia> Grid = create_CartGrid(size=(10,20),x=(0.,10), z=(2.,10))\nGrid{Float64, 2}\n size: (10, 20)\n length: (10.0, 8.0)\n domain: x ∈ [0.0, 10.0], z ∈ [2.0, 10.0]\n grid spacing Δ: (1.1111111111111112, 0.42105263157894735)\n\nAn example with dimensional units:\n\njulia> CharDim = GEO_units()\njulia> Grid = create_CartGrid(size=(10,20),x=(0.0km, 10km), z=(-20km, 10km), CharDim=CharDim)\nCartGrid{Float64, 2}\n size: (10, 20)\n length: (0.01, 0.03)\n domain: x ∈ [0.0, 0.01], z ∈ [-0.02, 0.01]\n grid spacing Δ: (0.0011111111111111111, 0.0015789473684210528)\n\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.create_partitioning_file-Tuple{String, Int64}","page":"List of functions","title":"GeophysicalModelGenerator.create_partitioning_file","text":"create_partitioning_file(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\", verbose=true)\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.create_profile_volume!-Tuple{ProfileData, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.create_profile_volume!","text":"create_profile_volume!(Profile::ProfileData, VolData::AbstractGeneralGrid; DimsVolCross::NTuple=(100,100), Depth_extent=nothing)\n\nCreates a cross-section through a volumetric 3D dataset VolData with the data supplied in Profile. Depth_extent can be the minimum & maximum depth for vertical profiles\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cross_section-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.cross_section","text":"cross_section(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)\n\nCreates a cross-section through a GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nDepending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\nVolume data: data will be interpolated or directly extracted from the data set.\nSurface data: surface data will be interpolated or directly extracted from the data set\nPoint data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\nInterpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS\n'section_width' indicates the maximal distance within which point data will be projected to the profile\n\nExample:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = cross_section(Data_set3D, Depth_level=-100km)\nGeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cross_section_points-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.cross_section_points","text":"function cross_section_points(P::GeoData; Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, section_width=50 )\n\nCreates a projection of separate points (saved as a GeoData object) onto a chosen plane. Only points with a maximum distance of section_width are taken into account\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cross_section_surface-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.cross_section_surface","text":"crosssectionsurface(Surface::GeoData; dims=(100,), Interpolate=false, Depthlevel=nothing; Latlevel=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a surface (2D) GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points. Start and End points will be in km!\nIMPORTANT: The surface to be extracted has to be given as a gridded GeoData object. It may also contain NaNs where it is not defined. Any points lying outside of the defined surface will be considered NaN.\n\nExample:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,-50km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set2D = GeoData(Lon,Lat,Depth,(Depth=Depth,));\njulia> Data_cross = cross_section_surface(Data_set2D, Lat_level =15)\nGeoData\n size : (100,)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 15.0 : 15.0]\n depth ϵ [ NaN : NaN]\n fields : (:Depth,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.cross_section_volume-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.cross_section_volume","text":"crosssectionvolume(Volume::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depthlevel=nothing; Latlevel=nothing; Lonlevel=nothing; Start=nothing, End=nothing, Depthextent=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nWhen both Start=(lon,lat) & End=(lon,lat) are given, one can also provide a the depth extent of the profile by providing Depthextent=(depthmin,depth_max)\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\nDepth_extent is an optional parameter that can indicate the depth extent over which you want to interpolate the vertical cross-section. Default is the full vertical extent of the 3D dataset\n\nExample:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = cross_section_volume(Data_set3D, Depth_level=-100km)\nGeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.distance_to_linesegment-Union{Tuple{_T}, Tuple{Tuple{_T, _T}, Tuple{_T, _T}, Tuple{_T, _T}}} where _T<:Number","page":"List of functions","title":"GeophysicalModelGenerator.distance_to_linesegment","text":"distance_to_linesegment(p::NTuple{2,_T}, v::NTuple{2,_T}, w::NTuple{2,_T})\n\nComputes the distance normal distance from a point p to a line segment defined by the points v and w.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.download_data","page":"List of functions","title":"GeophysicalModelGenerator.download_data","text":"download_data(url::String, local_filename=\"temp.dat\"; dir=pwd(), maxattempts=5 )\n\nDownloads a remote dataset with name url from a remote location and saves it to the current directory. If download fails, we make maxattempts attempts before giving up.\n\nExample\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\";\njulia> download_data(url)\n\"/Users/kausb/.julia/dev/GeophysicalModelGenerator/temp.dat\"\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.drape_on_topo-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.drape_on_topo","text":"drape_on_topo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.drape_on_topo-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.drape_on_topo","text":"Topo = drape_on_topo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.extract_ProfileData!","page":"List of functions","title":"GeophysicalModelGenerator.extract_ProfileData!","text":"extract_ProfileData!(Profile::ProfileData,VolData::GeoData, SurfData::NamedTuple, PointData::NamedTuple; DimsVolCross=(100,100),Depth_extent=nothing,DimsSurfCross=(100,),section_width=50)\n\nExtracts data along a vertical or horizontal profile\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.extract_ProfileData-Tuple{String, Int64, String}","page":"List of functions","title":"GeophysicalModelGenerator.extract_ProfileData","text":"extract_ProfileData(ProfileCoordFile::String,ProfileNumber::Int64,DataSetFile::String; DimsVolCross=(100,100),DepthVol=nothing,DimsSurfCross=(100,),WidthPointProfile=50km)\n\nThis is a convenience function (mostly for backwards compatibility with the MATLAB GUI) that loads the data from file & projects it onto a profile\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.extract_subvolume-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.extract_subvolume","text":"extract_subvolume(V::CartData; Interpolate=false, X_level=nothing, Y_level=nothing, Z_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n2D Example along a cross-section through 3D data:\n\njulia> X,Y,Z = xyz_grid(10:20,30:40,-300:25:0);\njulia> Data = Z.*2\njulia> Data_Int = Int64.(Data)\njulia> DataSet_Cart = CartData(X,Y,Z,(Data=Data,Data_Int=Data_Int, Velocity=(X,Y,Z)))\n\njulia> Data_cross = cross_section(DataSet_Cart, Start=(11.0,35), End=(19, 39.0))\nCartData\n size : (100, 100, 1)\n x ϵ [ 11.0 : 19.0]\n y ϵ [ 35.0 : 39.0]\n z ϵ [ -300.0 : 0.0]\n fields : (:Data, :Data_Int, :Velocity, :FlatCrossSection)\n attributes: [\"note\"]\n\njulia> Data_extracted = extract_subvolume(Data_cross, X_level=(1,7), Z_level=(-200,-100))\n CartData\n size : (50, 50, 1)\n x ϵ [ 11.894427190999917 : 17.260990336999413]\n y ϵ [ 35.44721359549995 : 38.130495168499706]\n z ϵ [ -200.0 : -100.0]\n fields : (:FlatCrossSection, :Data, :Data_Int, :Velocity)\n attributes: [\"note\"]\njulia> typeof(Data_extracted.fields.Data_Int)\n Array{Int64, 3}\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.extract_subvolume-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.extract_subvolume","text":"extract_subvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.find_slab_distance!-Tuple{Any, Any, Any, Any, Any, Any, Any, Trench}","page":"List of functions","title":"GeophysicalModelGenerator.find_slab_distance!","text":"find_slab_distance!(ls, d, X,Y,Z, trench::Trench)\n\nFunction that finds the perpendicular distance to the top and bottom of the slab d, and the current length of the slab l.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.fit_surface_to_points-Tuple{CartData, Vector, Vector, Vector}","page":"List of functions","title":"GeophysicalModelGenerator.fit_surface_to_points","text":"surf_new = fit_surface_to_points(surf::CartData, lon_pt::Vector, lat_pt::Vector, depth_pt::Vector)\n\nThis fits the depth values of the surface surf to the depth value of the closest-by-points in (lon_pt,lat_pt, depth_pt)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.fit_surface_to_points-Tuple{GeoData, Vector, Vector, Vector}","page":"List of functions","title":"GeophysicalModelGenerator.fit_surface_to_points","text":"surf_new = fit_surface_to_points(surf::GeoData, lon_pt::Vector, lat_pt::Vector, depth_pt::Vector)\n\nThis fits the depth values of the surface surf to the depth value of the closest-by-points in (lon_pt,lat_pt, depth_pt)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.flatten_cross_section-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.flatten_cross_section","text":"flatten_cross_section(V::CartData)\n\nTakes a diagonal 3D crosssection and flattens it to be converted to a 2D Grid by createCartGrid\n\nExample\n\nGrid = create_CartGrid(size=(100,100,100), x=(0.0km, 99.9km), y=(-10.0km, 20.0km), z=(-40km,4km));\nX,Y,Z = xyz_grid(Grid.coord1D...);\nDataSet = CartData(X,Y,Z,(Depthdata=Z,));\n\nData_Cross = cross_section(DataSet, dims=(100,100), Interpolate=true, Start=(ustrip(Grid.min[1]),ustrip(Grid.max[2])), End=(ustrip(Grid.max[1]), ustrip(Grid.min[2])))\n\nx_new = flatten_cross_section(Data_Cross)\n\n# This flattened cross_section can be added to original Data_Cross by addfield()\n\nData_Cross = addfield(Data_Cross,\"FlatCrossSection\", x_new)\nCartData\n size : (100, 100, 1)\n x ϵ [ 0.0 : 99.9]\n y ϵ [ -10.0 : 20.0]\n z ϵ [ -40.0 : 4.0]\n fields : (:Depthdata, :FlatCrossSection)\n attributes: [\"note\"]\n\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.flatten_cross_section-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.flatten_cross_section","text":"flatten_cross_section(V::GeoData)\nThis function takes a 3D cross section through a GeoData structure and computes the distance along the cross section for later 2D processing/plotting\n```julia-repl\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = cross_section(Data_set3D, Start=(10,30),End=(20,40))\njulia> x_profile = flatten_cross_section(Data_cross)\njulia> Data_cross = addfield(Data_cross,\"x_profile\",x_profile)\n\n```\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.flatten_index_dimensions-Tuple{Any, Vector{CartesianIndex{3}}}","page":"List of functions","title":"GeophysicalModelGenerator.flatten_index_dimensions","text":"ind2D = flatten_index_dimensions(Phase, ind_vec::Vector{CartesianIndex{3}})\n\nThis converts the indices to purely 2D indices if the array phase is 2D\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.flip","page":"List of functions","title":"GeophysicalModelGenerator.flip","text":"Data = flip(Data::GeoData, dimension=3)\n\nThis flips the data in the structure in a certain dimension (default is z [3])\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.get_processor_partitioning-Tuple{Any}","page":"List of functions","title":"GeophysicalModelGenerator.get_processor_partitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = get_processor_partitioning(filename; is64bit=false)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.getlonlatdepthmag_QuakeML-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.getlonlatdepthmag_QuakeML","text":"Data = getlonlatdepthmag_QuakeML(filename::String)\n\nExtracts longitude, latitude, depth and magnitude from a QuakeML file that has been e.g. downloaded from ISC. The data is then returned in GeoData format.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.inpoly-Union{Tuple{T}, Tuple{AbstractVector{T}, AbstractVector{T}, T, T}} where T<:Real","page":"List of functions","title":"GeophysicalModelGenerator.inpoly","text":"inpoly(PolyX::Vector, PolyY::Vector, x::Number, y::Number, iSteps::Vector, jSteps::)\n\nChecks if a point given by x and y is in or on (both cases return true) a polygon given by PolyX and PolyY, iSteps and jSteps provide the connectivity between the polygon edges. This function should be used through inpolygon!().\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.inpoly_fast-Union{Tuple{T}, Tuple{Vector{T}, Vector{T}, T, T}} where T<:Real","page":"List of functions","title":"GeophysicalModelGenerator.inpoly_fast","text":"inpoly_fast(PolyX::Vector, PolyY::Vector, x::Number, y::Number, iSteps::Vector, jSteps::)\n\nFaster version of inpoly() but will miss some points that are on the edge of the polygon.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.inpolygon!-Union{Tuple{T}, Tuple{Matrix{Bool}, Vector{T}, Vector{T}, Matrix{T}, Matrix{T}}} where T<:Real","page":"List of functions","title":"GeophysicalModelGenerator.inpolygon!","text":"inpolygon!(INSIDE::Matrix, PolyX::Vector, PolyY::Vector, X::Matrix, Y::Matrix; fast=false)\n\nChecks if points given by matrices X and Y are in or on (both cases return true) a polygon given by PolyX and PolyY. Boolean fast will trigger faster version that may miss points that are exactly on the edge of the polygon. Speedup is a factor of 3.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.inpolygon!-Union{Tuple{T}, Tuple{Vector{Bool}, AbstractVector{T}, AbstractVector{T}, Vector{T}, Vector{T}}} where T<:Real","page":"List of functions","title":"GeophysicalModelGenerator.inpolygon!","text":"inpolygon!(inside::Vector, PolyX::Vector, PolyY::Vector, x::Vector, y::Vector; fast=false)\n\nSame as above but inside, X and Y and are vectors.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_data_fields_cross_section-Tuple{CartData, Vararg{Any, 4}}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_data_fields_cross_section","text":"interpolate_data_fields_cross_section(V::CartData, X,Y,Z,Xcross)\n\nInterpolates data fields along a cross-section defined by Xcross and Z\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_data_surface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_data_surface","text":"Surf_interp = interpolate_data_surface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_data_surface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_data_surface","text":"Surf_interp = interpolate_data_surface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf.\n\nExample\n\njulia> Data\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = interpolate_data_surface(Data, surf)\n ParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields-Tuple{AbstractGeneralGrid, Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields","text":"Data_interp = interpolate_datafields(V::AbstractGeneralGrid, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = xyz_grid(x, y, z);\njulia> Data = Z\njulia> Data_set1= CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\njulia> X,Y,Z = xyz_grid(0:4:10, -1:.1:1, -5:.1:1 );\njulia> Data_set2= interpolate_datafields(Data_set1, X,Y,Z)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields-Tuple{UTMData, Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields","text":"interpolate_datafields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{CartData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"interpolate_datafields_2D(V::CartData, X, Y)\n\nInterpolates a data field V on a 2D CartData grid defined by X,Y. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"interpolate_datafields_2D(Original::CartData, New::CartData; Rotate=0.0, Translate=(0,0,0), Scale=(1.0,1.0,1.0))\n\nInterpolates a data field Original on a 2D CartData grid New. Typically used for horizontal surfaces.\n\nNote: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{GeoData, AbstractRange, AbstractRange}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"Surf_interp = interpolate_datafields_2D(V::GeoData, x::AbstractRange, y::AbstractRange; Lat::Number, Lon::Number)\n\nInterpolates a 3D data set V with a projection point proj=(Lat, Lon) on a plane defined by x and y, where x and y are uniformly spaced. Returns the 2D array Surf_interp.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{GeoData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"interpolate_datafields_2D(V::GeoData, Lon, Lat)\n\nInterpolates a data field V on a 2D grid defined by Lon,Lat. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"interpolate_datafields_2D(Original::GeoData, New::GeoData; Rotate=0.0, Translate=(0,0,0), Scale=(1.0,1.0,1.0))\n\nInterpolates a data field Original on a 2D GeoData grid New. Typically used for horizontal surfaces.\n\nNote: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.interpolate_datafields_2D-Tuple{UTMData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.interpolate_datafields_2D","text":"interpolate_datafields_2D(V::UTMData, EW, NS)\n\nInterpolates a data field V on a 2D grid defined by UTM. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.is_surface-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.is_surface","text":"issurf = is_surface(surf::AbstractGeneralGrid)\n\nReturns true if surf is a horizontal 3D surface.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.isinside_closed_STL","page":"List of functions","title":"GeophysicalModelGenerator.isinside_closed_STL","text":"inside = isinside_closed_STL(mesh::Mesh, Pt, eps=1e-3)\n\nDetermine whether a point Pt is inside a 3D closed triangular *.stl surface or not.\n\nThis implements the winding number method, following the python code: https://github.com/marmakoide/inside-3d-mesh\n\nThis again is described in the following paper by Alec Jacobson, Ladislav Kavan and Olga Sorkine-Hornung.\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.lithostatic_pressure!-Union{Tuple{N}, Tuple{T}, Tuple{Array{T, N}, Array{T, N}, Number}} where {T, N}","page":"List of functions","title":"GeophysicalModelGenerator.lithostatic_pressure!","text":"lithostatic_pressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"load_GMG(filename::String, dir=pwd(); maxattempts=5)\n\nLoads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it. We make maxattempts attempts to download it before giving up.\n\nExample 1 - Load local file\n\njulia> data = load_GMG(\"test\")\nGeoData \n size : (4, 3, 3)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 19.0]\n depth ϵ [ -20.0 : -10.0]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\nExample 2 - remote download\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\"\njulia> load_GMG(url)\nGeoData \n size : (149, 242, 1)\n lon ϵ [ -24.875 : 35.375]\n lat ϵ [ 34.375 : 71.375]\n depth ϵ [ -11.76 : -34.7]\n fields : (:MohoDepth,)\n attributes: [\"author\", \"year\"]\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG-Tuple{GMG_Dataset}","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"data::NamedTuple = load_GMG(data::GMG_Dataset)\n\nLoads a dataset specified in GMG_Dataset data and returns it as a named tuple\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG-Tuple{Vector{GMG_Dataset}}","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"Data = load_GMG(Datasets::Vector{GMG_Dataset})\n\nThis loads all the active datasets in Datasets, and returns a NamedTuple with Volume, Surface, Point, Screenshot and Topography data\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_dataset_file-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.load_dataset_file","text":"Datasets = load_dataset_file(file_datasets::String)\n\nThis loads a CSV textfile that lists datasets, which is expected to have the following format:\n\nName,Location,Type, [Active]\nAlpArray,./Seismicity/ALPARRAY/AlpArraySeis.jld2,Point, true\nPlomerova2022,https://seafile.rlp.net/f/abccb8d3302b4ef5af17/?dl=1,Volume\n\nNote that the first line of the file is skipped.\n\nHere, the meaning of the variables is:\n\nName: The name of the dataset to be loaded\nLocation: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with \"http\".\nType: type of the dataset (Volume, Surface, Point, Screenshot)\nActive: Do we want this file to be loaded or not? Optional parameter that defaults to true\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.lonlatdepth_grid-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.lonlatdepth_grid","text":"Lon, Lat, Depth = lonlatdepth_grid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.make_paraview_collection-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.make_paraview_collection","text":"make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = \".vts\", time = nothing)\n\nIn case one has a list of *.vtk files, this routine creates a *.pvd file that can be opened in Paraview. This is useful if you previously saved vtk files but didnt save it as a collection in the code itself.\n\nOptional options\n\ndir: directory where the *.vtk are stored.\npvd_name: filename of the resulting *.pvd file without extension; if not specified, full_simulation is used.\nfiles: Vector of the *.vtk files without extension; if not specified, all *.vtk files in the directory are used.\nfile_extension: file extension of the vtk files. Default is .vts but all vt* work.\ntime: Vector of the timesteps; if not specified, pseudo time steps are assigned.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.make_volc_topo-Tuple{LaMEM_grid}","page":"List of functions","title":"GeophysicalModelGenerator.make_volc_topo","text":"makevolctopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by readLaMEMinputfile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = read_LaMEM_inputfile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = make_volc_topo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = make_volc_topo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> write_paraview(Topo,\"VolcanoTopo\") # Save topography to paraview\nSaved file: VolcanoTopo.vts\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.meshgrid-Union{Tuple{T}, Tuple{AbstractVector{T}, AbstractVector{T}, AbstractVector{T}}} where T","page":"List of functions","title":"GeophysicalModelGenerator.meshgrid","text":"meshgrid(vx,vy,vz)\n\nComputes an (x,y,z)-grid from the vectors (vx,vy,vz). For more information, see the MATLAB documentation.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.movie_from_images-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.movie_from_images","text":"movie_from_images(; dir=pwd(), file=nothing, outfile=nothing, framerate=10, copy_to_current_dir=true, type=:mp4_default, collect=true)\n\nThe typical way to create animations with Paraview is to use the Save Animation option to save a series of *.png images.\n\nThis function combines these images to an *.mp4 movie.\n\nOptional options\n\ndir: directory where the images are stored.\nfile: filename of the image series without extension and numbers. Required if >1 image series is stored in the same directory. By default we reconstruct this name from the available files.\noutfile: filename of the resulting movie without extension; if not specified, file is used.\nframerate: number of frames/second.\ncopy_to_current_dir: copies the final movie to the current directory if true (default); otherwise it will be stored in dir.\ntype: type of movie that is created; possible options are:\n:mp4_default: Default option that saves a well-compressed mp4 movie that works well for us on ipad and embedded in a powerpoint presentation.\n:mov_hires: Higher-resolution quicktime movie (larger filesize & not compatible with windows)\ncollect: suppresses output of FFMPEG if true (default).\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.movie_paraview-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.movie_paraview","text":"pvd = movie_paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the write_paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = movie_paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = write_paraview(Data, name, pvd=movie, time=itime)\nend\nmovie_paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.nearest_point_indices-Tuple{Array, Array, Array, Vector, Vector, Vector}","page":"List of functions","title":"GeophysicalModelGenerator.nearest_point_indices","text":"ind = nearest_point_indices(X::Array,Y::Array,Z::Array, X_pt::Vector,Y_pt::Vector,Z_pt::Vector)\n\nReturns the index of the nearest point in (X_pt,Y_pt,Z_pt) to (X,Y,Z) and returns the index\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.nearest_point_indices-Tuple{Array, Array, Vector, Vector}","page":"List of functions","title":"GeophysicalModelGenerator.nearest_point_indices","text":"ind = nearest_point_indices(X::Array,Y::Array, X_pt::Vector, Y_pt::Vector)\n\nReturns the index of the nearest point in (X_pt,Y_pt) to (X,Y) and returns the index\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.nearest_point_indices-Tuple{Array, Vector}","page":"List of functions","title":"GeophysicalModelGenerator.nearest_point_indices","text":"ind = nearest_point_indices(X::Array, X_pt::Vector)\n\nReturns the index of the nearest point in (X_pt) to (X) and returns the index\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.parse_columns_CSV-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.parse_columns_CSV","text":"parse_columns_CSV(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = parse_columns_CSV(data_file, 4)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_in_tetrahedron-Union{Tuple{_T}, NTuple{5, _T}, Tuple{_T, _T, _T, _T, _T, Any}} where _T<:Vector{Float64}","page":"List of functions","title":"GeophysicalModelGenerator.point_in_tetrahedron","text":"inside = point_in_tetrahedron(p::_T, a::_T, b::_T, c::_T, d::_T, tol=1e-10)\n\nDetermines if a point p is inside a tetrahedron specified by a,b,c,d or not \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_to_nearest_grid-NTuple{6, Any}","page":"List of functions","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"count = point_to_nearest_grid(pt_x,pt_y,pt_z, X,Y,Z; radius_factor=1)\n\nThis uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_to_nearest_grid-Tuple{Any, Any, Any, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"Grid_counts = point_to_nearest_grid(pt_x,pt_y,pt_z, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_to_nearest_grid-Tuple{Any, Any, Any, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"Grid_counts = point_to_nearest_grid(pt_x,pt_y,pt_z, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_to_nearest_grid-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"Grid_counts = point_to_nearest_grid(Point::CartData, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.point_to_nearest_grid-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"Grid_counts = point_to_nearest_grid(Point::GeoData, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.project_CartData-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.project_CartData","text":"d_cart = project_CartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.project_CartData-Tuple{CartData, GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.project_CartData","text":"d_cart = project_CartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.project_CartData-Tuple{CartData, UTMData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.project_CartData","text":"d_cart = project_CartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.project_FEData_CartData-Tuple{CartData, FEData}","page":"List of functions","title":"GeophysicalModelGenerator.project_FEData_CartData","text":"data_cart = project_FEData_CartData(data_cart::CartData, data_fe::FEData)\n\nProjects a FEData object with tetrahedrons (e.g., from Gmsh) to a Cartesian grid\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.read_ASAGI-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.read_ASAGI","text":"data::CartData = read_ASAGI(fname_asagi::String)\n\nThis reads a 3D ASAGI NetCDF file, which is used as input for a number of codes such as SeisSol. It returns a CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.read_LaMEM_inputfile-Tuple{Any}","page":"List of functions","title":"GeophysicalModelGenerator.read_LaMEM_inputfile","text":"Grid::LaMEM_grid = read_LaMEM_inputfile(file, args::Union{String,Nothing}=nothing)\n\nParses a LaMEM input file and stores grid information in the Grid structure. Optionally, you can pass LaMEM command-line arguments as well.\n\nExample 1\n\njulia> Grid = read_LaMEM_inputfile(\"SaltModels.dat\")\nLaMEM Grid:\nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\nExample 2 (with command-line arguments)\n\njulia> Grid = read_LaMEM_inputfile(\"SaltModels.dat\", args=\"-nel_x 64 -coord_x -4,4\")\nLaMEM Grid:\n nel : (64, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 96, 96)\n x ϵ [-4.0 : 4.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.read_data_PVTR-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.read_data_PVTR","text":"Data::ParaviewData = read_data_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = read_data_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.read_data_VTR-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.read_data_VTR","text":"coord, Data_3D_Arrays, Name_Vec = read_data_VTR(fname)\n\nReads a VTR (structured grid) VTK file fname and extracts the coordinates, data arrays and names of the data. In general, this only contains a piece of the data, and one should open a *.pvtr file to retrieve the full data\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.read_picked_profiles-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.read_picked_profiles","text":"This reads the picked profiles from disk and returns a vector of ProfileData\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.remove_NaN_surface!-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.remove_NaN_surface!","text":"remove_NaN_surface!(Z::Array,X::Array,Y::Array)\n\nRemoves NaN's from a grid Z by taking the closest points as specified by X and Y.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.removefield-Tuple{AbstractGeneralGrid, String}","page":"List of functions","title":"GeophysicalModelGenerator.removefield","text":"V = removefield(V::AbstractGeneralGrid,field_name::String)\n\nRemoves the field with name field_name from the GeoData or CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.removefield-Tuple{AbstractGeneralGrid, Symbol}","page":"List of functions","title":"GeophysicalModelGenerator.removefield","text":"V = removefield(V::AbstractGeneralGrid,field_name::Symbol)\n\nRemoves the field with name field_name from the GeoData or CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.removefield-Union{Tuple{N}, Tuple{AbstractGeneralGrid, Tuple{Vararg{Symbol, N}}}} where N","page":"List of functions","title":"GeophysicalModelGenerator.removefield","text":"V = removefield(V::AbstractGeneralGrid,field_name::NTuple{N,Symbol})\n\nRemoves the fields in the tuple field_name from the GeoData or CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.rotate_translate_scale-Tuple{Union{CartData, ParaviewData}}","page":"List of functions","title":"GeophysicalModelGenerator.rotate_translate_scale","text":"Data_R = rotate_translate_scale(Data::Union{ParaviewData, CartData}; Rotate=0, Translate=(0,0,0), Scale=(1.0,1.0,1.0), Xc=(0.0,0.0))\n\nDoes an in-place rotation, translation and scaling of the Cartesian dataset Data.\n\nParameters\n\nNote that we apply the transformations in exactly this order:\n\nScale: scaling applied to the x,y,z coordinates of the data set\nRotate: rotation around the x/y axis (around the center of the box)\nTranslate: translation\nXc: center of rotation\n\nExample\n\njulia> X,Y,Z = xyz_grid(10:20,30:40,-50:-10);\njulia> Data_C = ParaviewData(X,Y,Z,(Depth=Z,))\nParaviewData\n size : (11, 11, 41)\n x ϵ [ 10.0 : 20.0]\n y ϵ [ 30.0 : 40.0]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\njulia> Data_R = rotate_translate_scale(Data_C, Rotate=30);\njulia> Data_R\nParaviewData\n size : (11, 11, 41)\n x ϵ [ 8.169872981077807 : 21.83012701892219]\n y ϵ [ 28.16987298107781 : 41.83012701892219]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.save_GMG-Tuple{String, Union{CartData, GeoData, UTMData}}","page":"List of functions","title":"GeophysicalModelGenerator.save_GMG","text":"save_GMG(filename::String, data::Union{GeoData, CartDat, UTMData}; dir=pwd())\n\nSaves the dataset data to a JLD2 file (name without extension) in the directory dir\n\nExample\n\njulia> Lon3D,Lat3D,Depth3D = lonlatdepth_grid(1.0:3:10.0, 11.0:4:20.0, (-20:5:-10)*km);\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Depth3D,)) \njulia> save_GMG(\"test\",Data_set)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.save_LaMEM_markers_parallel-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.save_LaMEM_markers_parallel","text":"save_LaMEM_markers_parallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true, is64bit=false)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using read_LaMEM_inputfile.\n\nExample\n\njulia> Grid = read_LaMEM_inputfile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> save_LaMEM_markers_parallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> save_LaMEM_markers_parallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.save_LaMEM_topography-Tuple{CartData, String}","page":"List of functions","title":"GeophysicalModelGenerator.save_LaMEM_topography","text":"save_LaMEM_topography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.screenshot_to_CartData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.screenshot_to_CartData","text":"Data = screenshot_to_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as screenshot_to_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.screenshot_to_GeoData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.screenshot_to_GeoData","text":"screenshot_to_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true, fieldname::Symbol=:colors)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.screenshot_to_UTMData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.screenshot_to_UTMData","text":"Data = screenshot_to_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true, fieldname=:colors)\n\nDoes the same as screenshot_to_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.spacing-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.spacing","text":"dlon, dlat = spacing(lon,lat)\n\nComputes the spacing with central differences\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.subtract_horizontalmean-Union{Tuple{AbstractArray{T, 3}}, Tuple{T}} where T","page":"List of functions","title":"GeophysicalModelGenerator.subtract_horizontalmean","text":"V_sub = subtract_horizontalmean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.subtract_horizontalmean-Union{Tuple{AbstractMatrix{T}}, Tuple{T}} where T","page":"List of functions","title":"GeophysicalModelGenerator.subtract_horizontalmean","text":"V_sub = subtract_horizontalmean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.swap_yz_dims-Tuple{FEData}","page":"List of functions","title":"GeophysicalModelGenerator.swap_yz_dims","text":"fe_swap = swap_yz_dims(fe_data::FEData)\n\nThis swaps the y and z dimensions of the FEData object, which is useful for pTatin as it uses y for what is z in GMG.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.velocity_spherical_to_cartesian!-Tuple{GeoData, Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.velocity_spherical_to_cartesian!","text":"velocity_spherical_to_cartesian!(Data::GeoData, Velocity::Tuple)\n\nIn-place conversion of velocities in spherical velocities [Veast, Vnorth, Vup] to cartesian coordinates (for use in paraview).\n\nNOTE: the magnitude of the vector will be the same, but the individual [Veast, Vnorth, Vup] components will not be retained correctly (as a different [x,y,z] coordinate system is used in paraview). Therefore, if you want to display or color that correctly in Paraview, you need to store these magnitudes as separate fields\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.votemap-Tuple{Vector{GeoData}, Vector{String}}","page":"List of functions","title":"GeophysicalModelGenerator.votemap","text":"votemap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values.\n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData\n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a votemap which combines the two data sets with:\n\njulia> Data_VoteMap = votemap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData\n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:votemap,)\n\nYou can also create a votemap of a single dataset:\n\njulia> Data_VoteMap = votemap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:votemap,)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.voxel_grav-NTuple{4, Array{Float64, 3}}","page":"List of functions","title":"GeophysicalModelGenerator.voxel_grav","text":"voxel_grav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients\n\nRequired arguments:\n\nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)\nRHO: 3D matrix with the density at each grid point [kg/m^3]\n\nOptional arguments:\n\nrefMod: 1D vector with the reference density for each depth. Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. In that case, one of the corners of RHO is used as reference model.In case of \"AVG\" the reference model is the average of each depth slice.\nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\"\nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]\nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output)\noutName: name of the paraview output (do not include file type)\nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_ASAGI-Tuple{String, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.write_ASAGI","text":"write_ASAGI(fname::String, Data::CartData; \n fields::Union{Nothing, Tuple}=nothing, \n km_to_m::Bool=false)\n\nWrites a CartData structure Data to an ASAGI file, which can be read by SeisSol or ExaHype. You can optionally pass a tuple with fields to be written. Note that we can only write individual (scalar) fields to disk, so vector or tensor fields needs to be split first\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_FEmesh_fields-Tuple{FEData}","page":"List of functions","title":"GeophysicalModelGenerator.write_FEmesh_fields","text":"write_FEmesh_fields(data::FEData)\n\nWrites cell and vertex fields to disk to be read by pTatin\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_FEmesh_mesh-Tuple{FEData}","page":"List of functions","title":"GeophysicalModelGenerator.write_FEmesh_mesh","text":"write_FEmesh_mesh(vdata::FEData; out_file=\"md.bin\", connectivity_zero_based=true)\n\nWrites a binary file with the mesh information for pTatin\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_pTatin_mesh-Tuple{FEData}","page":"List of functions","title":"GeophysicalModelGenerator.write_pTatin_mesh","text":"write_pTatin_mesh(fe_mesh::FEData; out_file=\"md.bin\", connectivity_zero_based=true)\n\nWrite a binary file with the mesh information for pTatin\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_pTatin_mesh-Tuple{Q1Data}","page":"List of functions","title":"GeophysicalModelGenerator.write_pTatin_mesh","text":"write_pTatin_mesh(q1_mesh::Q1Data; out_file=\"md.bin\", connectivity_zero_based=true)\n\nWrite a binary file with the mesh information for pTatin\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_paraview","page":"List of functions","title":"GeophysicalModelGenerator.write_paraview","text":"pvd = write_paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> write_paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> write_paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> write_paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> write_paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> write_paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> write_paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_paraview-2","page":"List of functions","title":"GeophysicalModelGenerator.write_paraview","text":"write_paraview(DataSet::Q1Data, filename=\"test\"; directory=nothing, pvd=nothing, time=nothing, verbose=true)\n\nWrites a Q1Data dataset to disk, which has cell and vertex field\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_paraview-3","page":"List of functions","title":"GeophysicalModelGenerator.write_paraview","text":"write_paraview(DataSet::FEData, filename=\"test\"; directory=nothing, pvd=nothing, time=nothing, verbose=true)\n\nWrites a FEData dataset (general finite element) to disk, which has cell and vertex field\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_paraview-Tuple{CartData, Any}","page":"List of functions","title":"GeophysicalModelGenerator.write_paraview","text":"write_paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.write_paraview-Tuple{UTMData, Any}","page":"List of functions","title":"GeophysicalModelGenerator.write_paraview","text":"write_paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.xyz_grid-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.xyz_grid","text":"X,Y,Z = xyz_grid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as lonlatdepth_grid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = xyz_grid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee lonlatdepth_grid for more examples.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#WhereTheWaterFlows.waterflows","page":"List of functions","title":"WhereTheWaterFlows.waterflows","text":"Topo_water, sinks, pits, bnds = waterflows(Topo::GeoData;\n flowdir_fn=WhereTheWaterFlows.d8dir_feature, feedback_fn=nothing, drain_pits=true, bnd_as_sink=true,\n rainfall = nothing,\n minsize=300)\n\nTakes a GMG GeoData object of a topographic map and routes water through the grid. Optionally, you can specify rainfall in which case we accumulate the rain as specified in this 2D array instead of the cellarea. This allows you to, for example, sum, up water if you have variable rainfall in the area. The other options are as in the waterflows function of the package WhereTheWaterFlows.\n\nExample\n\n# Download some topographic data\njulia> Topo = import_topo([6.5,7.3,50.2,50.6], file=\"@earth_relief_03s\");\n\n# Flow the water through the area:\njulia> Topo_water, sinks, pits, bnds = waterflows(Topo)\njulia> Topo_water\nGeoData\n size : (961, 481, 1)\n lon ϵ [ 6.5 : 7.3]\n lat ϵ [ 50.2 : 50.59999999999999]\n depth ϵ [ 0.045 : 0.724]\n fields : (:Topography, :area, :slen, :dir, :nout, :nin, :c)\n\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"EditURL = \"../../../tutorials/Tutorial_GPS.jl\"","category":"page"},{"location":"man/tutorial_GPS/#Import-and-visualize-GPS-data","page":"11 - Plot GPS vectors","title":"Import and visualize GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"11 - Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"In this tutorial, we discuss how to read the GPS data of Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7, which can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 You will also learn how to visualize them as vector data in Paraview.","category":"page"},{"location":"man/tutorial_GPS/#1.-Load-data","page":"11 - Plot GPS vectors","title":"1. Load data","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"We start with loading the required packages, which includes DataFrames and CSV to read the GPS data.","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"using GeophysicalModelGenerator\nusing DataFrames, CSV","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Read in coordinates of the grids (not stations as they are given in a different reference frame)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Note: the Vz velocity is given on a fully regular grid; yet Ve/Vn only on on-land stations which makes this a bit tricky.","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"The approach we take here is to first read in the Vz data points & reshape it to 2D matrixes Next, we read the Ve/Vn data and add them to the Vz grid","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Download the data:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"download_data(\"https://store.pangaea.de/Publications/Sanchez-etal_2018/ALPS2017_DEF_VT.GRD\",\"ALPS2017_DEF_VT.GRD\")","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ')\n\nnum_columns = 4;\ndata = parse_columns_CSV(data_file, num_columns); #Read numerical data from the file\nlon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3]","category":"page"},{"location":"man/tutorial_GPS/#2.-Check-and-reshape-vertical-velocity","page":"11 - Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"using Plots\nPlots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Reshape data to 2D (and 3D) matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"lon[:,:,1] = reshape(lon_Vz,(41,31))\nlat[:,:,1] = reshape(lat_Vz,(41,31))\nVz[:,:,1] = reshape(Vz_vec,(41,31))\n\nVz = Vz*1000 #in mm/year (original data in m/yr)\nVe = ones(size(Vz))*NaN\nVn = ones(size(Vz))*NaN","category":"page"},{"location":"man/tutorial_GPS/#3.-Load-horizontal-velocities","page":"11 - Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Next, we load the horizontal velocities which is available in the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"download_data(\"https://store.pangaea.de/Publications/Sanchez-etal_2018/ALPS2017_DEF_HZ.GRD\",\"ALPS2017_DEF_HZ.GRD\")\ndata_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ')\ndata = parse_columns_CSV(data_file, 10)\nlon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4]","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"(Image: Tutorial_GPS_2) So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Ve_Hz = Ve_Hz*1000; #in mm/year\nVn_Hz = Vn_Hz*1000; #in mm/year\n\nfor i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\nend\n\nVmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2) # velocity magnitude in mm/yr","category":"page"},{"location":"man/tutorial_GPS/#4.-Interpolate-topography-on-grid","page":"11 - Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Finally, it would be nice to put the data points on the topography. The elevation of the points is not given in the GPS dataset, so we use GMT to extract a topographic grid and interpolate the elevation on the GPS grid locations","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"using GMT, Interpolations","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"We use the import_topo function to read the topography from a file:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Elevation = import_topo([3,17,42,50], file=\"@earth_relief_01m\");\nnothing #hide","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"We now want to interpolate the elevation on the GPS grid locations.","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Lon_vec = NumValue(Elevation.lon)[:,1,1];\nLat_vec = NumValue(Elevation.lat)[1,:,1];\ninterpol = LinearInterpolation((Lon_vec, Lat_vec), NumValue(Elevation.depth)[:,:,1]); # create interpolation object\nheight = interpol.(lon,lat)/1e3","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"At this stage we have lon/lat/height of all points as well as velocity components","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Save paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"write_paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"","category":"page"},{"location":"man/tutorial_GPS/","page":"11 - Plot GPS vectors","title":"11 - Plot GPS vectors","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxel_grav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxel_grav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxel_grav","page":"Gravity code","title":"GeophysicalModelGenerator.voxel_grav","text":"voxel_grav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients\n\nRequired arguments:\n\nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)\nRHO: 3D matrix with the density at each grid point [kg/m^3]\n\nOptional arguments:\n\nrefMod: 1D vector with the reference density for each depth. Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. In that case, one of the corners of RHO is used as reference model.In case of \"AVG\" the reference model is the average of each depth slice.\nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\"\nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]\nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output)\noutName: name of the paraview output (do not include file type)\nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/visualise/#Visualisation","page":"Visualisation","title":"Visualisation","text":"","category":"section"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the visualise widget, which uses GLMakie and allows you to explore the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> using GeophysicalModelGenerator, GLMakie\njulia> using GMT, JLD2","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> ;\nshell> cd ~/Downloads/Zhao_etal_2016_data/ ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Now you can use the backspace key to return to the REPL, where we will load the data","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Data = JLD2.load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\"); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"At this stage you can look at it with","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> visualise(Data); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Note that this tends to take a while, the first time you do this (faster afterwards).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Let's add topography to the plot as well, which requires us to first load that:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Topo = import_topo([0,18,38,52], file=\"@earth_relief_01m.grd\");\njulia> visualise(Data, Topography=Topo); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Which will look like: (Image: Tutorial_Visualize)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> p=ProjectionPoint(Lon=10, Lat=45)\nProjectionPoint(45.0, 10.0, 578815.302916711, 4.983436768349297e6, 32, true)\njulia> Data_Cart = CartData(xyz_grid(-600:10:600,-600:10:600,-1000:10:-1));\njulia> Topo_Cart = CartData(xyz_grid(-600:10:600,-600:10:600,0));\njulia> Topo_Cart = project_CartData(Topo_Cart, Topo, p)\nCartData \n size : (121, 121, 1)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -3.6270262031545473 : 3.654942280296281]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Data_Cart = project_CartData(Data_Cart, Data, p)\nCartData \n size : (121, 121, 100)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -1000.0 : -10.0]\n fields : (:dVp_Percentage,)\n attributes: [\"note\"]","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"And once we have done that, you can visualize the data in the same way:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> visualise(Data_Cart, Topography=Topo_Cart)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"visualise","category":"page"},{"location":"man/tutorial_UTM/#Read-in-UTM-data","page":"12 - Read UTM data","title":"Read in UTM data","text":"","category":"section"},{"location":"man/tutorial_UTM/#Goal","page":"12 - Read UTM data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004","category":"page"},{"location":"man/tutorial_UTM/#Steps","page":"12 - Read UTM data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_UTM/#1.-Download-and-import-UTM-data:","page":"12 - Read UTM data","title":"1. Download and import UTM data:","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)\t\t\t\t\t\n# when using the data please cite as: \t\t\t\t\t\n# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004\nX COORD (UTM Zone 32N)\tY COORD (UTM Zone 32N)\tTOP (m.a.s.l)\tTHICKNESS (m)\tDENSITY (Kg/m3)\n286635\t4898615\t-24823.2533\t70418.125\t3305\n286635\t4918615\t-25443.48901\t69410.01563\t3305\n286635\t4938615\t-28025.24511\t66402.49219\t3305\n286635\t4958615\t-32278.13135\t61663.48438\t3305\n286635\t4978615\t-35885.5625\t57459.14063\t3305\n286635\t4998615\t-37270.9812\t55318.71094\t3305\n286635\t5018615\t-36134.30481\t55497.16406\t3305\n286635\t5038615\t-34866.0697\t55555.41406\t3305","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"2019-004_Spooner_Lithospheric Mantle.txt\",skipstart=4)\n1023×5 Matrix{Float64}:\n 286635.0 4.89862e6 -24823.3 70418.1 3305.0\n 286635.0 4.91862e6 -25443.5 69410.0 3305.0\n 286635.0 4.93862e6 -28025.2 66402.5 3305.0\n 286635.0 4.95862e6 -32278.1 61663.5 3305.0\n ⋮ \n 926635.0 5.45862e6 -35302.7 83215.6 3335.0\n 926635.0 5.47862e6 -34908.6 84203.0 3335.0\n 926635.0 5.49862e6 -34652.4 85398.3 3335.0","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> ew,ns,depth,thick,rho = data[:,1], data[:,2], data[:,3], data[:,4], data[:,5];","category":"page"},{"location":"man/tutorial_UTM/#2.-Check-and-reshape-vertical-velocity","page":"12 - Read UTM data","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> res = (length(unique(ns)), length(unique(ew)), 1)\njulia> EW = reshape(ew,res) \njulia> NS = reshape(ns,res)\njulia> Depth = reshape(depth,res)\njulia> T = reshape(thick,res)\njulia> Rho = reshape(rho,res)","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"Next we can examine EW: ","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> EW\n31×33×1 Array{Float64, 3}:\n[:, :, 1] =\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n ⋮ ⋮ ⋱ ⋮ \n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> EW = permutedims(EW,[2 1 3]) \njulia> NS = permutedims(NS,[2 1 3]) \njulia> Depth = permutedims(Depth,[2 1 3]) \njulia> T = permutedims(T,[2 1 3]) \njulia> Rho = permutedims(Rho,[2 1 3]) ","category":"page"},{"location":"man/tutorial_UTM/#3.-Create-UTMData-structure","page":"12 - Read UTM data","title":"3. Create UTMData structure","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"Next we can add the data to the UTMData structure. In this, we use the information that the UTM zone was 32 North.","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> Data_LM = UTMData(EW,NS,Depth,32, true, (Thickness=T/1e3*km, Density=Rho*kg/m^3 ))\nUTMData \n UTM zone : 32-32 North\n size : (33, 31, 1)\n EW ϵ [ 286635.0 : 926635.0]\n NS ϵ [ 4.898615e6 : 5.498615e6]\n depth ϵ [ -52579.56788 m : -20873.400850000003 m]\n fields : (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/#4.-Saving-and-plotting-in-Paraview","page":"12 - Read UTM data","title":"4. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"We can transfer this into a GeoData structure as:","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> Data_LM_lonlat = convert(GeoData,Data_LM)\nGeoData \n size : (33, 31, 1)\n lon ϵ [ 6.046903388679526 : 14.892535147436673]\n lat ϵ [ 44.11618022783332 : 49.64004892531006]\n depth ϵ [ -52.57956788 km : -20.873400850000003 km]\n fields: (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"and save it to Paraview in the usual way","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"julia> write_paraview(Data_LM_lonlat, \"Data_LM_lonlat\")","category":"page"},{"location":"man/tutorial_UTM/","page":"12 - Read UTM data","title":"12 - Read UTM data","text":"Opening and plotting the vertical field gives: (Image: Tutorial_UTM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.\nCreate movies for representation of earthquake or wave propagation.\nCreate geodynamic input models (for LaMEM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"10 - ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"10 - ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"10 - ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#1.-Download-data","page":"10 - ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#2.-Read-data-into-Julia","page":"10 - ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package CSV.jl to read in the data, and tell it that the data is separated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric formats (e.g. date, time etc.), we will use our helper function parsecolumnsCSV to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"julia> data = parse_columns_CSV(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> write_paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"The result looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"10 - ISC earthquake data","title":"10 - ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#3D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"8 - Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"8 - Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"8 - Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#1.-Download-data","page":"8 - Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#2.-Read-data-into-Julia","page":"8 - Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is separated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.-Reformat-the-data","page":"8 - Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.1-Load-and-plot-the-data-layout","page":"8 - Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Lon,Lat,Depth = lonlatdepth_grid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.2-Interpolate-to-a-regular-grid","page":"8 - Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this: ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Using the nearest point to the regular grid points (by using the nearest_point_indices function) \nEmploy GMT.jl\nUse GeoStats.jl.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2));\njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2));\n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#4.-Generate-Paraview-file","page":"8 - Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,))\nGeoData\n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,)\njulia> write_paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#5.-Plotting-data-in-Paraview","page":"8 - Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#6.-Julia-script","page":"8 - Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"8 - Interpolate irregular 3D seismic tomography","title":"8 - Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials. We have a range of tutorials that show the functionality of GeophysicalModelGenerator.jl (see sidebar). They are mostly stand-alone so it doesn't matter in which order they are executed. The input scripts for the tutorials are available under /tutorials.","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"EditURL = \"../../../tutorials/Tutorial_Basic.jl\"","category":"page"},{"location":"man/Tutorial_Basic/#Getting-started","page":"1 - Getting started","title":"Getting started","text":"","category":"section"},{"location":"man/Tutorial_Basic/#Aim:","page":"1 - Getting started","title":"Aim:","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"The aim of this tutorial is to give you a feeling for the GeophysicalModelGenerator package.","category":"page"},{"location":"man/Tutorial_Basic/#1.-Loading-data","page":"1 - Getting started","title":"1. Loading data","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"We start with loading the package, and assume that you have installed it:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"using GeophysicalModelGenerator;","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Lets load a first 3D seismic tomography data set of the Alps. We uploaded an example file on Zenodo here, which comes from the paper of Paffrath et al. 2021. We can load this in GMG with:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Tomo_Alps_full = load_GMG(\"https://zenodo.org/records/10738510/files/Paffrath_2021_SE_Pwave.jld2?download=1\")","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"GeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 : 31.0385]\n fields : (:dVp_Percentage,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"This is a so-called GeoData object, which is a 3D grid of seismic velocities as a function of longitude, latitude and depth, which can include various fields (here we only have a single field: :dVp_Percentage) We can save this in VTK format, which is a widely used format that can for exampke be read by the 3D open-source visualization tool Paraview:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"write_paraview(Tomo_Alps_full,\"Tomo_Alps_full\")","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Tomo_Alps_full.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"We also uploaded a dataset with the topography of the Alpine region which can be downloaded with:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Topo_Alps = load_GMG(\"https://zenodo.org/records/10738510/files/AlpsTopo.jld2?download=1\")","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"GeoData\n size : (961, 841, 1)\n lon ϵ [ 4.0 : 20.0]\n lat ϵ [ 36.0 : 50.0]\n depth ϵ [ -4.181 : 4.377]\n fields : (:Topography,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Different than the 3D tomographic model, the topography has size 1 for the last index which indicates that this is a 3D surface. As you can see, the depth varies, which is because it is a warped surface. We can write this to disk as well","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"write_paraview(Topo_Alps,\"Topo_Alps\")","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Topo_Alps.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"If we open both datasets in Paraview, and changing both files from outline/solid colors to the corresponding data field, we see: (Image: Basic_Tutorial_1) Now we can change the colormap on the right side, marked by a red square. For topography we use the Oleron colormap, which you can download here. For the tomography we use the Roma scientific colormap. You will now see a blue'ish box of the tomography, this is not the best color to visualise the data. Let's invert the colormap by clicking on the item marked by the blue arrow. Now we see the tomography in a more intuitive way, but the topography is not visible anymore. We can change the opacity of the tomography by setting a value in the Opacity field marked by the red square. Note that you will need to adapt the range of the topography colormap as the change in color is not at 0.0. By clicking on the item marked by the black arrow, you can set your desired range.","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"(Image: Basic_Tutorial_1)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Now you should see something like this: (Image: Basic_Tutorial_1)","category":"page"},{"location":"man/Tutorial_Basic/#2.-Extract-subset-of-data","page":"1 - Getting started","title":"2. Extract subset of data","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"As you can see the tomographic data covers a much larger area than the Alps itself, and in most of that area there is no data. It is thus advantageous to cut out a piece of the dataset that we are interested in which can be done with extract_subvolume:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Tomo_Alps = extract_subvolume(Tomo_Alps_full,Lon_level=(4,20),Lat_level=(36,50), Depth_level=(-600,-10))\n\nwrite_paraview(Tomo_Alps,\"Tomo_Alps\");","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Tomo_Alps.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"After loading the new data again in paraview, switching to the proper data field and adjusting the colormap, you should see something like this: (Image: Basic_Tutorial_2)","category":"page"},{"location":"man/Tutorial_Basic/#3.-Create-cross-sections","page":"1 - Getting started","title":"3. Create cross sections","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Paraview has the option to Slice through the data but it is not very intuitive to do this in 3D. Another limitation of Paraview is that it does not have native support for spherical coordinates, and therefore the data is translated to cartesian (x,y,z) coordinates (with the center of the Earth at (0,0,0)). That makes this a bit cumbersome to make a cross-section at a particular location. If you are interested in this you can use the cross_section function:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"data_200km = cross_section(Tomo_Alps, Depth_level=-200)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"GeoData\n size : (54, 60, 1)\n lon ϵ [ 3.9057 : 19.9057]\n lat ϵ [ 35.9606 : 49.8976]\n depth ϵ [ -202.0385 : -202.0385]\n fields : (:dVp_Percentage, :FlatCrossSection)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"As you see, this is not exactly at 200 km depth, but at the closest z-level in the data sets. If you want to be exactly at 200 km, use the Interpolate option:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"data_200km_exact = cross_section(Tomo_Alps, Depth_level=-200, Interpolate=true)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"GeoData\n size : (100, 100, 1)\n lon ϵ [ 3.9057 : 19.9057]\n lat ϵ [ 35.9606 : 49.8976]\n depth ϵ [ -200.0 : -200.0]\n fields : (:dVp_Percentage, :FlatCrossSection)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"In general, you can get help info for all functions with ?:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"help?> cross_section\nsearch: cross_section cross_section_volume cross_section_points cross_section_surface flatten_cross_section\n\n cross_section(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)\n\n Creates a cross-section through a GeoData object.\n\n • Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified\n\n • They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\n\n • Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\n 1. Volume data: data will be interpolated or directly extracted from the data set.\n\n 2. Surface data: surface data will be interpolated or directly extracted from the data set\n\n 3. Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\n • Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA\n SETS\n\n • 'section_width' indicates the maximal distance within which point data will be projected to the profile\n\n Example:\n ≡≡≡≡≡≡≡≡\n\n julia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\n julia> Data = Depth*2; # some data\n julia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\n julia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\n julia> Data_cross = cross_section(Data_set3D, Depth_level=-100km)\n GeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Let's use this to make a vertical cross-section as well:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Cross_vert = cross_section(Tomo_Alps, Start=(5,47), End=(15,44))","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"GeoData\n size : (100, 100, 1)\n lon ϵ [ 5.0 : 15.0]\n lat ϵ [ 47.0 : 44.0]\n depth ϵ [ -606.0385 : -15.5769]\n fields : (:dVp_Percentage, :FlatCrossSection)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"And write them to paraview:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"write_paraview(Cross_vert,\"Cross_vert\");\nwrite_paraview(data_200km,\"data_200km\");","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Cross_vert.vts\nSaved file: data_200km.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"After loading the data in Paraview, you can use the Clip tool on the topography to only show the topography above sealevel and make it 60% transparent. Also adjust the colormap of the tomography to 5.0 and -5.0","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"(Image: Basic_Tutorial_3)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"After doing all these steps, you should see something like this: (Image: Basic_Tutorial_3)","category":"page"},{"location":"man/Tutorial_Basic/#4.-Cartesian-data","page":"1 - Getting started","title":"4. Cartesian data","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"As you can see, the curvature or the Earth is taken into account here. Yet, for many applications it is more convenient to work in Cartesian coordinates (kilometers) rather then in geographic coordinates. GeophysicalModelGenerator has a number of tools for this. First we need do define a ProjectionPoint around which we project the data","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"proj = ProjectionPoint(Lon=12.0,Lat =43)\n\nTopo_cart = convert2CartData(Topo_Alps, proj)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"CartData\n size : (961, 841, 1)\n x ϵ [ -748.7493528015041 : 695.3491277129204]\n y ϵ [ -781.2344794653393 : 831.6826244089501]\n z ϵ [ -4.181 : 4.377]\n fields : (:Topography,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"And do the same with the tomography:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Tomo_cart = convert2CartData(Tomo_Alps, proj)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"CartData\n size : (54, 60, 39)\n x ϵ [ -757.8031278236692 : 687.0608438357591]\n y ϵ [ -785.601866956207 : 821.3433749818317]\n z ϵ [ -606.0385 : -15.5769]\n fields : (:dVp_Percentage,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Save:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"write_paraview(Tomo_cart,\"Tomo_cart\");\nwrite_paraview(Topo_cart,\"Topo_cart\");","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Tomo_cart.vts\nSaved file: Topo_cart.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"(Image: Basic_Tutorial_4) As the coordinates are now aligned with the x,y,z coordinate axes in Paraview it is now straightforward to use the build-in tools to explore the data.","category":"page"},{"location":"man/Tutorial_Basic/#5.-Rectilinear-data","page":"1 - Getting started","title":"5. Rectilinear data","text":"","category":"section"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Yet, because of the curvature of the Earth, the resulting 3D model is not strictly rectilinear, which is often a requiment for cartesian numerical models. This can be achieved in a relatively straightforward manner, by creating a new 3D dataset that is slightly within the curved boundaries of the projected data set:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Tomo_rect = CartData(xyz_grid(-550.0:10:600, -500.0:10:700, -600.0:5:-17));","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"the routine project_CartData will then project the data from the geographic coordinates to the new rectilinear grid:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Tomo_rect = project_CartData(Tomo_rect, Tomo_Alps, proj)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"CartData\n size : (116, 121, 117)\n x ϵ [ -550.0 : 600.0]\n y ϵ [ -500.0 : 700.0]\n z ϵ [ -600.0 : -20.0]\n fields : (:dVp_Percentage,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"we can do the same with topography:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Topo_rect = CartData(xyz_grid(-550.0:1:600, -500.0:1:700, 0))\nTopo_rect = project_CartData(Topo_rect, Topo_Alps, proj)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"CartData\n size : (1151, 1201, 1)\n x ϵ [ -550.0 : 600.0]\n y ϵ [ -500.0 : 700.0]\n z ϵ [ -3.6366708734115245 : 4.2399313641768455]\n fields : (:Topography,)\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Save it:","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"write_paraview(Tomo_rect,\"Tomo_rect\");\nwrite_paraview(Topo_rect,\"Topo_rect\");","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"Saved file: Tomo_rect.vts\nSaved file: Topo_rect.vts\n","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"(Image: Basic_Tutorial_5)","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"At this stage, the data can directly be used to generate cartesian numerical model setups, as explained in the other tutorials.","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"","category":"page"},{"location":"man/Tutorial_Basic/","page":"1 - Getting started","title":"1 - Getting started","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/ptatin/#pTatin","page":"pTatin","title":"pTatin","text":"","category":"section"},{"location":"man/ptatin/","page":"pTatin","title":"pTatin","text":"We provide a few routines that allow exporting GMG input data sets to a format that can be read by the 3D geodynamic modelling software pTatin, which is an open-source Cartesian code to perform crustal and lithospheric-scale simulations. ","category":"page"},{"location":"man/ptatin/","page":"pTatin","title":"pTatin","text":"The Q1Data format can be saved directly to pTatin.","category":"page"},{"location":"man/ptatin/","page":"pTatin","title":"pTatin","text":"GeophysicalModelGenerator.write_pTatin_mesh\nGeophysicalModelGenerator.swap_yz_dims","category":"page"},{"location":"man/ptatin/#GeophysicalModelGenerator.write_pTatin_mesh","page":"pTatin","title":"GeophysicalModelGenerator.write_pTatin_mesh","text":"write_pTatin_mesh(fe_mesh::FEData; out_file=\"md.bin\", connectivity_zero_based=true)\n\nWrite a binary file with the mesh information for pTatin\n\n\n\n\n\nwrite_pTatin_mesh(q1_mesh::Q1Data; out_file=\"md.bin\", connectivity_zero_based=true)\n\nWrite a binary file with the mesh information for pTatin\n\n\n\n\n\n","category":"function"},{"location":"man/ptatin/#GeophysicalModelGenerator.swap_yz_dims","page":"pTatin","title":"GeophysicalModelGenerator.swap_yz_dims","text":"fe_swap = swap_yz_dims(fe_data::FEData)\n\nThis swaps the y and z dimensions of the FEData object, which is useful for pTatin as it uses y for what is z in GMG.\n\n\n\n\n\n","category":"function"},{"location":"man/code_of_conduct/","page":"Code of Conduct","title":"Code of Conduct","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/CODE_OF_CONDUCT.md\"","category":"page"},{"location":"man/code_of_conduct/#code-of-conduct","page":"Code of Conduct","title":"Code of Conduct","text":"","category":"section"},{"location":"man/code_of_conduct/","page":"Code of Conduct","title":"Code of Conduct","text":"Contributor Covenant Code of ConductOur PledgeWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.Our StandardsExamples of behavior that contributes to a positive environment for our community include:Demonstrating empathy and kindness toward other people\nBeing respectful of differing opinions, viewpoints, and experiences\nGiving and gracefully accepting constructive feedback\nAccepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\nFocusing on what is best not just for us as individuals, but for the overall communityExamples of unacceptable behavior include:The use of sexualized language or imagery, and sexual attention or advances of any kind\nTrolling, insulting or derogatory comments, and personal or political attacks\nPublic or private harassment\nPublishing others' private information, such as a physical or email address, without their explicit permission\nOther conduct which could reasonably be considered inappropriate in a professional settingEnforcement ResponsibilitiesCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.ScopeThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.EnforcementInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to Boris Kaus, Marcel Thielmann, or any other of the principal developers responsible for enforcement listed in Authors. All complaints will be reviewed and investigated promptly and fairly.All community leaders are obligated to respect the privacy and security of the reporter of any incident.Enforcement GuidelinesCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:1. CorrectionCommunity Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.2. WarningCommunity Impact: A violation through a single incident or series of actions.Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.3. Temporary BanCommunity Impact: A serious violation of community standards, including sustained inappropriate behavior.Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.4. Permanent BanCommunity Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.Consequence: A permanent ban from any sort of public interaction within the community.AttributionThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.[homepage]: https://www.contributor-covenant.orgFor answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#3D-tomography-model-that-is-given-as-a-netCDF-file","page":"3 - 3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3 - 3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3 - 3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#1.-Download-data","page":"3 - 3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#2.-Read-data-into-Julia","page":"3 - 3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> filename = (\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length\n--------------------------------------------------------------------------------------------------------------------------\ndepth 301\nlatitude 100\nlongitude 100\n\n##### Variables #####\n\nName Type Dimensions\n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth\nlatitude FLOAT latitude\nlongitude FLOAT longitude\nVs FLOAT longitude latitude depth\n\n##### Attributes #####\n\nVariable Name Value\n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de\nglobal data_revision r.0.0\nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1\nglobal id MeRE2020\nglobal author_name Amr EL-Sharkawy\nglobal comment model converted to netCDF by IRIS EMC\nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC\nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc\nglobal author_url https://www.seismologie.ifg.uni-kiel.de\nglobal reference El-Sharkawy, et al. (2020)\nglobal repository_name EMC\nglobal Conventions CF-1.0\nglobal Metadata_Conventions Unidata Dataset Discovery v1.0\nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km\ndepth long_name depth in km\ndepth display_name depth in km\ndepth positive down\nlatitude units degrees_north\nlatitude long_name Latitude; positive north\nlatitude standard_name latitude\nlongitude units degrees_east\nlongitude long_name Longitude; positive east\nlongitude standard_name longitude\nVs units km.s-1\nVs long_name Shear wave velocity\nVs display_name S Velocity (km/s)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions\n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth\nlatitude FLOAT latitude\nlongitude FLOAT longitude\nVs FLOAT longitude latitude depth","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regular grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the command ncread:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#3.-Reformat-the-coordinate-data","page":"3 - 3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\nLon3D,Lat3D,Depth3D = lonlatdepth_grid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#4.-Generate-Paraview-file","page":"3 - 3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> Data_set = GeoData(Lon3D,Lat3D,Depth3D,(Vs_km_s=Vs_3D,))\nGeoData\n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,)\njulia> write_paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#5.-Plotting-data-in-Paraview","page":"3 - 3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#6.-Julia-script","page":"3 - 3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3 - 3D seismic tomography from netCDF","title":"3 - 3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/gmsh/#Gmsh","page":"Gmsh","title":"Gmsh","text":"","category":"section"},{"location":"man/gmsh/","page":"Gmsh","title":"Gmsh","text":"Gmsh is a widely used 3D unstructured mesh generator that produces tetrahedral meshes which can be tagged by region. It is possible to import such meshes and use that to set region info in a GMG data set, or use it to generate pTatin input.","category":"page"},{"location":"man/gmsh/","page":"Gmsh","title":"Gmsh","text":"GeophysicalModelGenerator.import_Gmsh","category":"page"},{"location":"man/gmsh/#GeophysicalModelGenerator.import_Gmsh","page":"Gmsh","title":"GeophysicalModelGenerator.import_Gmsh","text":"import_Gmsh(fname::String)\n\nReads a Gmsh file. Requires loading GridapGmsh.\n\n\n\n\n\n","category":"function"},{"location":"man/asagi_io/#ASAGI-I/O","page":"ASAGI","title":"ASAGI I/O","text":"","category":"section"},{"location":"man/asagi_io/","page":"ASAGI","title":"ASAGI","text":"ASAGI is a fileformat that is used by codes such as SeisSol or ExaHype. It employs the NetCDF4 data format.","category":"page"},{"location":"man/asagi_io/","page":"ASAGI","title":"ASAGI","text":"We can read ASAGI files into GMG, and write GMG datasets to ASAGI format, which makes it straightforward to use GMG to create a model setup or to couple the results of geodynamic simulations (e.g., produced by LaMEM) with codes that support ASAGI.","category":"page"},{"location":"man/asagi_io/","page":"ASAGI","title":"ASAGI","text":"read_ASAGI\nwrite_ASAGI","category":"page"},{"location":"man/asagi_io/#GeophysicalModelGenerator.read_ASAGI","page":"ASAGI","title":"GeophysicalModelGenerator.read_ASAGI","text":"data::CartData = read_ASAGI(fname_asagi::String)\n\nThis reads a 3D ASAGI NetCDF file, which is used as input for a number of codes such as SeisSol. It returns a CartData dataset\n\n\n\n\n\n","category":"function"},{"location":"man/asagi_io/#GeophysicalModelGenerator.write_ASAGI","page":"ASAGI","title":"GeophysicalModelGenerator.write_ASAGI","text":"write_ASAGI(fname::String, Data::CartData; \n fields::Union{Nothing, Tuple}=nothing, \n km_to_m::Bool=false)\n\nWrites a CartData structure Data to an ASAGI file, which can be read by SeisSol or ExaHype. You can optionally pass a tuple with fields to be written. Note that we can only write individual (scalar) fields to disk, so vector or tensor fields needs to be split first\n\n\n\n\n\n","category":"function"},{"location":"man/movies/#Create-movies","page":"Movies","title":"Create movies","text":"","category":"section"},{"location":"man/movies/","page":"Movies","title":"Movies","text":"We have two routines to help create movies from the results. The first one takes *.png images generated with the Save Animation option in paraview and puts them together in compressed movies (either mp4 or mov):","category":"page"},{"location":"man/movies/","page":"Movies","title":"Movies","text":"movie_from_images","category":"page"},{"location":"man/movies/#GeophysicalModelGenerator.movie_from_images","page":"Movies","title":"GeophysicalModelGenerator.movie_from_images","text":"movie_from_images(; dir=pwd(), file=nothing, outfile=nothing, framerate=10, copy_to_current_dir=true, type=:mp4_default, collect=true)\n\nThe typical way to create animations with Paraview is to use the Save Animation option to save a series of *.png images.\n\nThis function combines these images to an *.mp4 movie.\n\nOptional options\n\ndir: directory where the images are stored.\nfile: filename of the image series without extension and numbers. Required if >1 image series is stored in the same directory. By default we reconstruct this name from the available files.\noutfile: filename of the resulting movie without extension; if not specified, file is used.\nframerate: number of frames/second.\ncopy_to_current_dir: copies the final movie to the current directory if true (default); otherwise it will be stored in dir.\ntype: type of movie that is created; possible options are:\n:mp4_default: Default option that saves a well-compressed mp4 movie that works well for us on ipad and embedded in a powerpoint presentation.\n:mov_hires: Higher-resolution quicktime movie (larger filesize & not compatible with windows)\ncollect: suppresses output of FFMPEG if true (default).\n\n\n\n\n\n","category":"function"},{"location":"man/movies/","page":"Movies","title":"Movies","text":"The other one creates *.pvd files that can be saved with the pvd=... optional option in write_paraview, such that you can animate temporal data in paraview (yif you're happy you can save the result as images and use movies_from_pics). See the corresponding tutorial on how to generate *.pvd files.","category":"page"},{"location":"man/movies/","page":"Movies","title":"Movies","text":"write_paraview","category":"page"},{"location":"man/movies/#GeophysicalModelGenerator.write_paraview","page":"Movies","title":"GeophysicalModelGenerator.write_paraview","text":"pvd = write_paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> write_paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> write_paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> write_paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> write_paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> write_paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> write_paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\nwrite_paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\nwrite_paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\nwrite_paraview(DataSet::Q1Data, filename=\"test\"; directory=nothing, pvd=nothing, time=nothing, verbose=true)\n\nWrites a Q1Data dataset to disk, which has cell and vertex field\n\n\n\n\n\nwrite_paraview(DataSet::FEData, filename=\"test\"; directory=nothing, pvd=nothing, time=nothing, verbose=true)\n\nWrites a FEData dataset (general finite element) to disk, which has cell and vertex field\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"cross_section\nextract_subvolume\ninterpolate_datafields\nvotemap\nsubtract_horizontalmean\nabove_surface\nbelow_surface\ninterpolate_data_surface\ninterpolate_topography_plane\nparse_columns_CSV\nrotate_translate_scale!\npoint_to_nearest_grid\nconvert2UTMzone\nconvert2CartData\nproject_CartData\ndrape_on_topo\nlithostatic_pressure!\ncountmap","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.extract_subvolume","page":"Tools","title":"GeophysicalModelGenerator.extract_subvolume","text":"extract_subvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\nextract_subvolume(V::CartData; Interpolate=false, X_level=nothing, Y_level=nothing, Z_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = lonlatdepth_grid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = extract_subvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n2D Example along a cross-section through 3D data:\n\njulia> X,Y,Z = xyz_grid(10:20,30:40,-300:25:0);\njulia> Data = Z.*2\njulia> Data_Int = Int64.(Data)\njulia> DataSet_Cart = CartData(X,Y,Z,(Data=Data,Data_Int=Data_Int, Velocity=(X,Y,Z)))\n\njulia> Data_cross = cross_section(DataSet_Cart, Start=(11.0,35), End=(19, 39.0))\nCartData\n size : (100, 100, 1)\n x ϵ [ 11.0 : 19.0]\n y ϵ [ 35.0 : 39.0]\n z ϵ [ -300.0 : 0.0]\n fields : (:Data, :Data_Int, :Velocity, :FlatCrossSection)\n attributes: [\"note\"]\n\njulia> Data_extracted = extract_subvolume(Data_cross, X_level=(1,7), Z_level=(-200,-100))\n CartData\n size : (50, 50, 1)\n x ϵ [ 11.894427190999917 : 17.260990336999413]\n y ϵ [ 35.44721359549995 : 38.130495168499706]\n z ϵ [ -200.0 : -100.0]\n fields : (:FlatCrossSection, :Data, :Data_Int, :Velocity)\n attributes: [\"note\"]\njulia> typeof(Data_extracted.fields.Data_Int)\n Array{Int64, 3}\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.interpolate_datafields","page":"Tools","title":"GeophysicalModelGenerator.interpolate_datafields","text":"Data_interp = interpolate_datafields(V::AbstractGeneralGrid, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = xyz_grid(x, y, z);\njulia> Data = Z\njulia> Data_set1= CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\njulia> X,Y,Z = xyz_grid(0:4:10, -1:.1:1, -5:.1:1 );\njulia> Data_set2= interpolate_datafields(Data_set1, X,Y,Z)\n\n\n\n\n\ninterpolate_datafields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.votemap","page":"Tools","title":"GeophysicalModelGenerator.votemap","text":"votemap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values.\n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData\n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a votemap which combines the two data sets with:\n\njulia> Data_VoteMap = votemap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData\n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:votemap,)\n\nYou can also create a votemap of a single dataset:\n\njulia> Data_VoteMap = votemap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:votemap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.subtract_horizontalmean","page":"Tools","title":"GeophysicalModelGenerator.subtract_horizontalmean","text":"V_sub = subtract_horizontalmean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = subtract_horizontalmean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.parse_columns_CSV","page":"Tools","title":"GeophysicalModelGenerator.parse_columns_CSV","text":"parse_columns_CSV(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = parse_columns_CSV(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.point_to_nearest_grid","page":"Tools","title":"GeophysicalModelGenerator.point_to_nearest_grid","text":"Grid_counts = point_to_nearest_grid(Point::CartData, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = point_to_nearest_grid(pt_x,pt_y,pt_z, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = point_to_nearest_grid(Point::GeoData, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = point_to_nearest_grid(pt_x,pt_y,pt_z, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\ncount = point_to_nearest_grid(pt_x,pt_y,pt_z, X,Y,Z; radius_factor=1)\n\nThis uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.lithostatic_pressure!","page":"Tools","title":"GeophysicalModelGenerator.lithostatic_pressure!","text":"lithostatic_pressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.countmap","page":"Tools","title":"GeophysicalModelGenerator.countmap","text":"DatasetcountMap = countmap(DataSet::GeoData,field::String,stepslon::Int64,stepslat::Int64)\n\nTakes a 2D GeoData struct and counts entries of field per predefined control area. field should only consist of 1.0s and 0.0s. The control area is defined by steplon and steplat. steplon is the number of control areas in longitude direction and steplat the number of control areas in latitude direction. The counts per control area are normalized by the highest count.\n\njulia> Data_Faults = GeoData(Lon3D,Lat3D,Faults,(Faults=Faults,))\nGeoData \n size : (375, 208, 1)\n lon ϵ [ -9.932408319802885 : 34.93985125012068]\n lat ϵ [ 35.086096468211394 : 59.919210145128545]\n depth ϵ [ 0.0 : 1.0]\n fields : (:Faults,)\n\njulia> steplon = 125\njulia> steplat = 70\njulia> countmap = countmap(Data_Faults,\"Faults\",steplon,steplat)\n\nGeoData \n size : (124, 69, 1)\n lon ϵ [ -9.751471789279 : 34.75891471959677]\n lat ϵ [ 35.26604656731949 : 59.73926004602028]\n depth ϵ [ 0.0 : 1.0]\n fields : (:countmap,)\n\njulia\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-topographic-data-and-drape-a-geological-map-on-top-of-it-(given-as-raster-graphics)","page":"9 - ETOPO1 Topography and geological maps","title":"Extract topographic data and drape a geological map on top of it (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"9 - ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"9 - ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#1.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"9 - ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example, we downloaded ETOPO1_Ice_g_gmt4 and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (to the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt. ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#2.-Create-a-tectonic-map-with-orthogonal-projection","page":"9 - ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#3.-Import-data-to-paraview","page":"9 - ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max], grid=true);\njulia> Lon,Lat,Depth = lonlatdepth_grid(G.x[1:end],G.y[1:end],0);\njulia> numel_topo = prod(size(Lon));\njulia> Depth[:,:,1] = 1e-3*G.z';\njulia> Topo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = (lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function screenshot_to_GeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> DataPNG = screenshot_to_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"Next, we drape the screenshot on the topographic map with drape_on_topo:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> TopoGeology = drape_on_topo(Topo, DataPNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#4.-Save","page":"9 - ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"julia> write_paraview(TopoGeology, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"9 - ETOPO1 Topography and geological maps","title":"9 - ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#1.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#2.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#3.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia>","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@1.6) pkg>","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell>","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#4.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.11) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#5.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia.\nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have).\nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"EditURL = \"../../../tutorials/Tutorial_FaultDensity.jl\"","category":"page"},{"location":"man/Tutorial_FaultDensity/#Fault-Density-Map","page":"17 - Fault Density Map","title":"Fault Density Map","text":"","category":"section"},{"location":"man/Tutorial_FaultDensity/#Goal","page":"17 - Fault Density Map","title":"Goal","text":"","category":"section"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"In this tutorial, Fault Data is loaded as Shapefiles, which is then transformed to raster data. With the help of that a fault density map of Europe is created.","category":"page"},{"location":"man/Tutorial_FaultDensity/#1.-Load-Data","page":"17 - Fault Density Map","title":"1. Load Data","text":"","category":"section"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Load packages:","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"using GeophysicalModelGenerator, Shapefile, Plots, Rasters, GeoDatasets, Interpolations","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Data is taken from \"Active Faults of Eurasia Database AFEAD v2022\" DOI:10.13140/RG.2.2.25509.58084 You need to download it manually (as it doesn't seem to work automatically), and can load the following file:","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"File = \"AFEAD_v2022/AFEAD_v2022.shp\"","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Load data using the Shapefile package:","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"table = Shapefile.Table(File)\ngeoms = Shapefile.shapes(table)\nCONF = table.CONF","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Raster the shapefile data","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"ind = findall((table.CONF .== \"A\") .| (table.CONF .== \"B\") .| (table.CONF .== \"C\"))\nfaults = Shapefile.Handle(File).shapes[ind]\nfaults = rasterize(last,faults; res=(0.12,0.12), missingval=0, fill=1, atol = 0.4, shape=:line)\nlon = faults.dims[1]\nlat = faults.dims[2]","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Download coastlines with GeoDatasets:","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"lonC,latC,dataC = GeoDatasets.landseamask(;resolution='l',grid=10)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Interpolate to fault grid","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"itp = linear_interpolation((lonC, latC), dataC)\ncoastlines = itp[lon.val,lat.val]\ncoastlines = map(y -> y > 1 ? 1 : y, coastlines)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Plot the fault data","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"heatmap(lon.val,lat.val,coastlines',legend=false,colormap=cgrad(:gray1,rev=true),alpha=0.4);\nplot!(faults; color=:red,legend = false,title=\"Fault Map World\",ylabel=\"Lat\",xlabel=\"Lon\")","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"(Image: tutorial_Fault_Map)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Restrict area to Europe","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"indlat = findall((lat .> 35) .& (lat .< 60))\nLat = lat[indlat]\nindlon = findall((lon .> -10) .& (lon .< 35))\nLon = lon[indlon]\ndata = faults.data[indlon,indlat]","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Create GeoData from restricted data","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Lon3D,Lat3D, Faults = lonlatdepth_grid(Lon,Lat,0);\nFaults[:,:,1] = data\nData_Faults = GeoData(Lon3D,Lat3D,Faults,(Faults=Faults,))","category":"page"},{"location":"man/Tutorial_FaultDensity/#2.-Create-Density-Map","page":"17 - Fault Density Map","title":"2. Create Density Map","text":"","category":"section"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Create a density map of the fault data. This is done with the countmap function. This function takes a specified field of a 2D GeoData struct and counts the entries in all control areas which are defined by steplon (number of control areas in lon direction) and steplat (number of control areas in lat direction). The field should only consist of 0.0 and 1.0 and the steplength. The final result is normalized by the highest count.","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"steplon = 188\nsteplat = 104\ncntmap = countmap(Data_Faults,\"Faults\",steplon,steplat)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Plot the density map with coastlines","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"lon = unique(cntmap.lon.val)\nlat = unique(cntmap.lat.val)\ncoastlinesEurope = itp[lon,lat]\ncoastlinesEurope = map(y -> y > 1 ? 1 : y, coastlinesEurope)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"Plot this using Plots.jl:","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"heatmap(lon,lat,coastlinesEurope',colormap=cgrad(:gray1,rev=true),alpha=1.0);\nheatmap!(lon,lat,cntmap.fields.countmap[:,:,1]',colormap=cgrad(:batlowW,rev=true),alpha = 0.8,legend=true,title=\"Fault Density Map Europe\",ylabel=\"Lat\",xlabel=\"Lon\")","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"(Image: tutorial_Fault_Map)","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"","category":"page"},{"location":"man/Tutorial_FaultDensity/","page":"17 - Fault Density Map","title":"17 - Fault Density Map","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"EditURL = \"../../../tutorials/Tutorial_Jura.jl\"","category":"page"},{"location":"man/Tutorial_Jura/#Create-a-3D-model-of-the-Jura-mountains","page":"19 - Jura tutorial","title":"Create a 3D model of the Jura mountains","text":"","category":"section"},{"location":"man/Tutorial_Jura/#Aim","page":"19 - Jura tutorial","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"In this tutorial, your will learn how to use drape a geological map on top of a digital topography model, import GeoTIFF surfaces and add cross-sections from screenshots to the model setup.","category":"page"},{"location":"man/Tutorial_Jura/#1.-Load-data","page":"19 - Jura tutorial","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We start with loading the required packages, which includes GMT to download topography (an optional dependency for GeophysicalModelGenerator)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"using GeophysicalModelGenerator, GMT","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Download the topography with:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Topo = import_topo(lat=[45.5,47.7], lon=[5, 8.1], file=\"@earth_relief_03s\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Next, we drape the geological map on top of the geological map. The geological map was taken from the 2021 PhD thesis of Marc Schori and saved as png map. We downloaded the pdf map, and cropped it to the lower left and upper right corners. The resulting map was uploaded to zenodo; it can be downloaded with","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"download_data(\"https://zenodo.org/records/10726801/files/SchoriM_Encl_01_Jura-map_A1.png\", \"SchoriM_Encl_01_Jura-map_A1.png\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We also used a slightly larger version of the map along with the online tool https://apps.automeris.io to extract the location of the corners (using the indicated blue lon/lat values on the map as reference points). This results in:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"lowerleft = [4.54602510460251, 45.27456049638056, 0.0]\nupperright = [8.948117154811715, 47.781282316442606, 0.0]","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We can now import the map with the Screensho_To_GeoData function:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Geology = screenshot_to_GeoData(\"SchoriM_Encl_01_Jura-map_A1.png\", lowerleft, upperright, fieldname=:geology_colors) # name should have \"colors\" in it","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"You can \"drape\" this image on the topographic map with","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"TopoGeology = drape_on_topo(Topo, Geology)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"GeoData\n size : (3721, 2641, 1)\n lon ϵ [ 5.0 : 8.1]\n lat ϵ [ 45.5 : 47.7]\n depth ϵ [ 0.157 : 4.783]\n fields : (:Topography, :geology_colors)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"In the same PhD thesis, Schori also reconstructed the depth of various layers within the Jura. The data of his thesis are uploaded to https://doi.org/10.5281/zenodo.5801197. Here, we use the basement topography as an example (/03_BMes_top-basement/BMes_Spline.tif), which is in the GeoTIFF format that contains coordinates. Unfortunately, there are a lot of coordinate systems and in the thesis of Schori, a mixture of longitude/latitude (longlat) and a Swiss reference system is used. Within GeophysicalModelGenerator, we need a longlat coordinate system. It is quite easy to convert one to the other with the open-source QGIS package. We did this and saved the resulting image in Zenodo:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"download_data(\"https://zenodo.org/records/10726801/files/BMes_Spline_longlat.tif\", \"BMes_Spline_longlat.tif\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Now, import the GeoTIFF as:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Basement = import_GeoTIFF(\"BMes_Spline_longlat.tif\", fieldname=:Basement, removeNaN_z=true)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"the removeNaN_z option removes NaN values from the dataset and instead uses the z-value of the nearest point. That is important if you want to use this surface to generate a 3D model setup (using below_surface, for example).","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"The thesis also provides a few interpreted vertical cross-sections. As before, we import them as a screenshot and estimate the lower-left and upper right corners. In this particular case, we are lucky that the lon/lat values are indicated on the cross-section. Often that is not the case and you have to use the mapview along with the digitizer tool described above to estimate this.","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"As example, we use the cross-section","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"download_data(\"https://zenodo.org/records/10726801/files/Schori_2020_Ornans-Miserey-v2_whiteBG.png\", \"Schori_2020_Ornans-Miserey-v2_whiteBG.png\")\nCorner_LowerLeft = (5.92507, 47.31300, -2.0)\nCorner_UpperRight = (6.25845, 46.99550, 2.0)\nCrossSection_1 = screenshot_to_GeoData(\"Schori_2020_Ornans-Miserey-v2_whiteBG.png\", Corner_LowerLeft, Corner_UpperRight) # name should have \"colors\" in it","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Note that we slightly modified the image to save it with a white instead of a transparent background","category":"page"},{"location":"man/Tutorial_Jura/#2.-Project-the-data-to-a-cartesian-grid","page":"19 - Jura tutorial","title":"2. Project the data to a cartesian grid","text":"","category":"section"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"At this stage, we have all data in geographic coordinates. In most cases it is more useful to have them in cartesian coordinates. Moreover, the resolution of the grids is different. Whereas the TopoGeology has a size of (3721, 2641, 1), Basement has size (2020, 1751, 1). It is often useful to have them on exactly the same size grid","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We can do this in two steps: First, we define a ProjectionPoint along which we perform the projection","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"proj = ProjectionPoint(Lon=6, Lat=46.5)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We can simply transfer the TopoGeology map to Cartesian values with:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"convert2CartData(Topo,proj)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CartData\n size : (3721, 2641, 1)\n x ϵ [ -82.31272066158422 : 162.66627630405523]\n y ϵ [ -115.08628070208057 : 136.73428093825373]\n z ϵ [ 0.157 : 4.783]\n fields : (:Topography,)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"The problem is that the result is not strictly orthogonal, but instead slightly curved. That causes issues later on when we want to intersect the surface with a 3D box. It is therefore better to use the project_CartData to project the GeoData structure to a CartData struct. Let's first create this structure by using x,y coordinates that are slightly within the ranges given above:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"TopoGeology_cart = CartData(xyz_grid(range(-70,150,length=3500), range(-105,130,length=2500), 0.0))","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CartData\n size : (3500, 2500, 1)\n x ϵ [ -75.0 : 160.0]\n y ϵ [ -110.0 : 135.0]\n z ϵ [ 0.0 : 0.0]\n fields : (:Z,)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Next, we project the data with:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"TopoGeology_cart = project_CartData(TopoGeology_cart, TopoGeology, proj)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CartData\n size : (3500, 2500, 1)\n x ϵ [ -80.0 : 160.0]\n y ϵ [ -110.0 : 135.0]\n z ϵ [ 0.16119615440200846 : 4.776083480822139]\n fields : (:Topography, :geology_colors)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"And we can do the same with the basement topography","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Basement_cart = project_CartData(TopoGeology_cart, Basement, proj)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CartData\n size : (3500, 2500, 1)\n x ϵ [ -80.0 : 160.0]\n y ϵ [ -110.0 : 135.0]\n z ϵ [ -6.049924561684904 : 0.8030737304687502]\n fields : (:Basement,)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Finally, we can also transfer the cross-section to cartesian coordinates. As this is just for visualization, we will use convert2CartData in this case","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CrossSection_1_cart = convert2CartData(CrossSection_1,proj)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"for visualization, it is nice if we can remove the part of the cross-section that is above the topography. We can do that with the below_surface routine which returns a Boolean to indicate whether points are below or above the surface","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"below = below_surface(CrossSection_1_cart, TopoGeology_cart)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We can add that to the cross-section with:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"CrossSection_1_cart = addfield(CrossSection_1_cart,\"rocks\",Int64.(below))","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Note that we transfer the boolean to an integer","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Let's have a look at this in Paraview:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"write_paraview(Basement_cart,\"Basement_cart\")\nwrite_paraview(TopoGeology_cart,\"TopoGeology_cart\")\nwrite_paraview(CrossSection_1_cart,\"CrossSection_1_cart\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"The result looks like: (Image: Jura_Tutorial_1)","category":"page"},{"location":"man/Tutorial_Jura/#3.-Geological-block-model","page":"19 - Jura tutorial","title":"3. Geological block model","text":"","category":"section"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Yet, if you want to perform a numerical simulation of the Jura, it is more convenient to rotate the maps such that we can perform a simulation perpendicular to the strike of the mountain belt. This can be done with rotate_translate_scale:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"RotationAngle = -43\nTopoGeology_cart_rot = rotate_translate_scale(TopoGeology_cart, Rotate=RotationAngle)\nBasement_cart_rot = rotate_translate_scale(Basement_cart, Rotate=RotationAngle)\nCrossSection_1_cart_rot = rotate_translate_scale(CrossSection_1_cart, Rotate=RotationAngle)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Next, we can create a new computational grid that is more conveniently oriented: We create both a surface and a 3D block","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"nx, ny, nz = 1024, 1024, 128\nx,y,z = range(-100,180,nx), range(-50,70,ny), range(-8,4,nz)\nComputationalSurf = CartData(xyz_grid(x,y,0))\nComputationalGrid = CartData(xyz_grid(x,y,z))","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Re-interpolate the rotated to the new grid:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"GeologyTopo_comp_surf = interpolate_datafields_2D(TopoGeology_cart_rot, ComputationalSurf, Rotate=RotationAngle)\nBasement_comp_surf = interpolate_datafields_2D(Basement_cart_rot, ComputationalSurf, Rotate=RotationAngle)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Next we can use the surfaces to create a 3D block model. We start with a block model that has the different rocktypes:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Phases = zeros(Int8,size(ComputationalGrid.x)) #Define rock types","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Set everything below the topography to 1","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"id = below_surface(ComputationalGrid, GeologyTopo_comp_surf)\nPhases[id] .= 1","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"The basement is set to 2","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"id = below_surface(ComputationalGrid, Basement_comp_surf)\nPhases[id] .= 2","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Add to the computational grid:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"ComputationalGrid = addfield(ComputationalGrid,\"Phases\", Phases)\nComputationalGrid = removefield(ComputationalGrid,\"Z\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"Save the surfaces, cross-section and the grid:","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"write_paraview(GeologyTopo_comp_surf,\"GeologyTopo_comp_surf\")\nwrite_paraview(Basement_comp_surf, \"Basement_comp_surf\")\nwrite_paraview(CrossSection_1_cart_rot,\"CrossSection_1_cart_rot\")\nwrite_paraview(ComputationalGrid,\"ComputationalGrid\")","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We can visualize this in paraview: (Image: Jura_Tutorial_2)","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"We use a vertical exaggeration of factor two. Also note that the y-direction is now perpendicular to the Jura mountains. The paraview statefiles to generate this figure is /tutorials/Jura_2.pvsm.","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"","category":"page"},{"location":"man/Tutorial_Jura/","page":"19 - Jura tutorial","title":"19 - Jura tutorial","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/paraview_collection/#Paraview-collection","page":"Paraview collection","title":"Paraview collection","text":"","category":"section"},{"location":"man/paraview_collection/","page":"Paraview collection","title":"Paraview collection","text":"We have one main routine to generate *.pvd files from existing vtk files. This is useful if no *.pvd file was generated during the simulation, or if you want to generate a *.pvd file from a collection of vtk files that were generated in different simulations. The *.pvd file can be used to animate temporal data in paraview. You can either provide a Vector of the files or the specific time step or the function reads the directory and assigns a pseudo time step to the *.pvd file.","category":"page"},{"location":"man/paraview_collection/","page":"Paraview collection","title":"Paraview collection","text":"GeophysicalModelGenerator.make_paraview_collection","category":"page"},{"location":"man/paraview_collection/#GeophysicalModelGenerator.make_paraview_collection","page":"Paraview collection","title":"GeophysicalModelGenerator.make_paraview_collection","text":"make_paraview_collection(; dir=pwd(), pvd_name=nothing, files=nothing, file_extension = \".vts\", time = nothing)\n\nIn case one has a list of *.vtk files, this routine creates a *.pvd file that can be opened in Paraview. This is useful if you previously saved vtk files but didnt save it as a collection in the code itself.\n\nOptional options\n\ndir: directory where the *.vtk are stored.\npvd_name: filename of the resulting *.pvd file without extension; if not specified, full_simulation is used.\nfiles: Vector of the *.vtk files without extension; if not specified, all *.vtk files in the directory are used.\nfile_extension: file extension of the vtk files. Default is .vts but all vt* work.\ntime: Vector of the timesteps; if not specified, pseudo time steps are assigned.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_Polygon_structures/#Adding-complex-geometries-to-a-model-setup-including-sedimentary-basins,-lithospheric-thinning-and-an-accretionary-prism","page":"23 - Build geometry from polygons","title":"Adding complex geometries to a model setup including sedimentary basins, lithospheric thinning and an accretionary prism","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/#Goal","page":"23 - Build geometry from polygons","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"This tutorial visualizes simplified geological as it is done here for a passive margin where lithospheric thinning, sedimentary basin and accretionary prism occur. The simplification is based on a polygon structure for a pseudo-3D model. While the structure can have a random shape in the x- and z-direction, in the y-direction only the extent is variable. ","category":"page"},{"location":"man/tutorial_Polygon_structures/#Steps","page":"23 - Build geometry from polygons","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/#1.-Set-up-your-simplified-background-model","page":"23 - Build geometry from polygons","title":"1. Set up your simplified background model","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"Before adding specific geological features, a general simplified model setup is necessary. The construction is made by using the add_box! function. For the model the discontinuities are in 15, 45, 145, and 945 km depth.","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"using GeophysicalModelGenerator\n\n# number of cells in every direction\nnx = 100\nny = 100\nnz = 200\n\n# define domain size\nx = LinRange(0.0,800.0,nx)\ny = LinRange(0.0,800.0,ny)\nz = LinRange(-660,50,nz)\nCart = CartData(xyz_grid(x, y, z))\n\n# initialize phase and temperature matrix\nPhase = fill(1,nx,ny,nz);\nTemp = fill(1350.0, nx,ny,nz);\n\n# add different phases: crust->2, Mantle Lithosphere->3 Mantle->1\nadd_box!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(-800.0,0.0), phase = LithosphericPhases(Layers=[15 30 100 800], Phases=[2 3 1 5], Tlab=1300 ), T=LinearTemp(Ttop=20, Tbot=1600))\n\n# add air phase 0\nadd_box!(Phase, Temp, Cart; xlim=(0.0,800.0),ylim=(0.0,800.0), zlim=(0.0,50.0), phase = ConstantPhase(0), T=ConstantTemp(20.0))","category":"page"},{"location":"man/tutorial_Polygon_structures/#2.-Add-polygon-structure","page":"23 - Build geometry from polygons","title":"2. Add polygon structure","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"To include the geological structures of a passive margin into the model, we use polygons for depths of up to 150 km. In the example, the sediment basin shows a more trapezoidal (2D in x-/z-direction) shape, while the thinning of the plate has a more triangular (2D in x-/z-direction). More complex structures can be build using arbitrarily sized polygons in x- and z-direction, wheraes in the y-direction only the length can be varied (specified by two values). The x- and z-values of the points need to be in the same order for selecting the correct point (P1(1/3), P2(2/2) –> xlim(1,2), ylim(3,2)).","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"# xlim: x-coordinates of the points, same ordering as zlim\n# zlim: z-coordinates of the points, same ordering as xlim\n# ylim: limits the object within the two ylim values\n# unlimited number of points possible to create the polygon\n\n# add sediment basin \nadd_polygon!(Phase, Temp, Cart; xlim=(0.0,0.0, 160.0, 200.0),ylim=(100.0,300.0), zlim=(0.0,-10.0,-20.0,0.0), phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));\n\n# add thinning of the continental crust attached to the slab and its thickness \nadd_polygon!(Phase, Temp, Cart; xlim=(0.0, 200.0, 0.0),ylim=(500.0,800.0), zlim=(-100.0,-150.0,-150.0), phase = ConstantPhase(5), T=LinearTemp(Ttop=1000, Tbot=1100));\n\n# add accretionary prism \nadd_polygon!(Phase, Temp, Cart; xlim=(800.0, 600.0, 800.0),ylim=(100.0,800.0), zlim=(0.0,0.0,-60.0), phase = ConstantPhase(8), T=LinearTemp(Ttop=20, Tbot=30));","category":"page"},{"location":"man/tutorial_Polygon_structures/#3.-Export-final-model-setup-to-a-paraview-file","page":"23 - Build geometry from polygons","title":"3. Export final model setup to a paraview file","text":"","category":"section"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"For visualisation and comparison to actual measured data, the mode setup is saved to a paraview file.","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"# # Save data to paraview:\nCart = addfield(Cart,(;Phase, Temp))\nwrite_paraview(Cart, \"Sedimentary_basin\");","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"After importing and looking at the file to paraview, some unresolved areas might be visible as they are visible in this model. That is due to the resolution and shape of the polygon. To reduce those artefacts an increase in resolution or a change of the polygon angle might help.","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"(Image: Tutorial_Polygon_structures)","category":"page"},{"location":"man/tutorial_Polygon_structures/","page":"23 - Build geometry from polygons","title":"23 - Build geometry from polygons","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, the easiest way to get started is by looking at LaMEM.jl which is integrated with GMG","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.read_LaMEM_inputfile\nGeophysicalModelGenerator.get_processor_partitioning\nGeophysicalModelGenerator.save_LaMEM_topography\nGeophysicalModelGenerator.save_LaMEM_markers_parallel\nGeophysicalModelGenerator.read_data_PVTR\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.create_partitioning_file","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.read_LaMEM_inputfile","page":"LaMEM","title":"GeophysicalModelGenerator.read_LaMEM_inputfile","text":"Grid::LaMEM_grid = read_LaMEM_inputfile(file, args::Union{String,Nothing}=nothing)\n\nParses a LaMEM input file and stores grid information in the Grid structure. Optionally, you can pass LaMEM command-line arguments as well.\n\nExample 1\n\njulia> Grid = read_LaMEM_inputfile(\"SaltModels.dat\")\nLaMEM Grid:\nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\nExample 2 (with command-line arguments)\n\njulia> Grid = read_LaMEM_inputfile(\"SaltModels.dat\", args=\"-nel_x 64 -coord_x -4,4\")\nLaMEM Grid:\n nel : (64, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 96, 96)\n x ϵ [-4.0 : 4.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.get_processor_partitioning","page":"LaMEM","title":"GeophysicalModelGenerator.get_processor_partitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = get_processor_partitioning(filename; is64bit=false)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.save_LaMEM_topography","page":"LaMEM","title":"GeophysicalModelGenerator.save_LaMEM_topography","text":"save_LaMEM_topography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.save_LaMEM_markers_parallel","page":"LaMEM","title":"GeophysicalModelGenerator.save_LaMEM_markers_parallel","text":"save_LaMEM_markers_parallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true, is64bit=false)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using read_LaMEM_inputfile.\n\nExample\n\njulia> Grid = read_LaMEM_inputfile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> save_LaMEM_markers_parallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> save_LaMEM_markers_parallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.read_data_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.read_data_PVTR","text":"Data::ParaviewData = read_data_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = read_data_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.create_partitioning_file","page":"LaMEM","title":"GeophysicalModelGenerator.create_partitioning_file","text":"create_partitioning_file(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\", verbose=true)\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"5 - Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"5 - Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"note: Note\nIt used to be tricky to get GMT.jl installed and working correctly on your system but that has improved since version 1.0 which now comes with precompiled binaries. So as long as you make sure that your GMT version is >1.0, it should work.","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"5 - Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#1.-Download-topographic-data-of-the-Alpine-region","page":"5 - Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function import_topo that simplifies this. Note that this function only is available once GMT is loaded. ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = import_topo([4,20,37,49], file=\"@earth_relief_01m\")\nGeoData \n size : (960, 720, 1)\n lon ϵ [ 4.0 : 19.983333333333334]\n lat ϵ [ 37.0 : 48.983333333333334]\n depth ϵ [ -3.8725 km : 4.2495 km]\n fields: (:Topography,)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"The data is available in different resolutions:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"Dataset Resolution Description\n\"@earth_relief_01s\" 1 arc sec SRTM tiles (14297 tiles, land only, 60S-60N) [NASA/USGS]\n\"@earth_relief_03s\" 3 arc sec SRTM tiles (14297 tiles, land only, 60S-60N) [NASA/USGS]\n\"@earth_relief_15s\" 15 arc sec SRTM15+ [David Sandwell, SIO/UCSD]\n\"@earth_relief_30s\" 30 arc sec SRTM30+ [Becker et al., 2009, SIO/UCSD]\n\"@earth_relief_01m\" 1 arc min ETOPO1 Ice surface [NEIC/NOAA]\n\"@earth_relief_02m\" 2 arc min ETOPO2v2 Ice surface [NEIC/NOAA]\n\"@earth_relief_03m\" 3 arc min ETOPO1 after Gaussian spherical filtering (5.6 km fullwidth)\n\"@earth_relief_04m\" 4 arc min ETOPO1 after Gaussian spherical filtering (7.5 km fullwidth)\n\"@earth_relief_05m\" 5 arc min ETOPO1 after Gaussian spherical filtering (9 km fullwidth)\n\"@earth_relief_06m\" 6 arc min ETOPO1 after Gaussia30n spherical filtering (10 km fullwidth)\n\"@earth_relief_10m\" 10 arc min ETOPO1 after Gaussian spherical filtering (18 km fullwidth)\n\"@earth_relief_15m\" 20 arc min ETOPO1 after Gaussian spherical filtering (28 km fullwidth)\n\"@earth_relief_20m\" 20 arc min ETOPO1 after Gaussian spherical filtering (37 km fullwidth)\n\"@earth_relief_30m\" 30 arc min ETOPO1 after Gaussian spherical filtering (55 km fullwidth)\n\"@earth_relief_60m\" 60 arc min ETOPO1 after Gaussian spherical filtering (111 km fullwidth)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"Generally, it is advisable to not use the largest resolution if you have a large area. ","category":"page"},{"location":"man/tutorial_GMT_Topography/#2.-Save","page":"5 - Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"Transforming this to Paraview is a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"julia> write_paraview(Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"5 - Create GMT-based topography","title":"5 - Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"}]
+}
diff --git a/dev/siteinfo.js b/dev/siteinfo.js
new file mode 100644
index 00000000..33434919
--- /dev/null
+++ b/dev/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "dev";
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..6a5afc30
--- /dev/null
+++ b/index.html
@@ -0,0 +1,2 @@
+
+
diff --git a/previews/PR67/.documenter-siteinfo.json b/previews/PR67/.documenter-siteinfo.json
new file mode 100644
index 00000000..390a686f
--- /dev/null
+++ b/previews/PR67/.documenter-siteinfo.json
@@ -0,0 +1 @@
+{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2024-02-29T14:40:37","documenter_version":"1.2.1"}}
\ No newline at end of file
diff --git a/previews/PR67/assets/documenter.js b/previews/PR67/assets/documenter.js
new file mode 100644
index 00000000..f5311607
--- /dev/null
+++ b/previews/PR67/assets/documenter.js
@@ -0,0 +1,889 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min',
+ 'minisearch': 'https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($) {
+$(document).ready(function() {
+ hljs.highlightAll();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+let timer = 0;
+var isExpanded = true;
+
+$(document).on("click", ".docstring header", function () {
+ let articleToggleTitle = "Expand docstring";
+
+ debounce(() => {
+ if ($(this).siblings("section").is(":visible")) {
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-down")
+ .addClass("fa-chevron-right");
+ } else {
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-right")
+ .addClass("fa-chevron-down");
+
+ articleToggleTitle = "Collapse docstring";
+ }
+
+ $(this)
+ .find(".docstring-article-toggle-button")
+ .prop("title", articleToggleTitle);
+ $(this).siblings("section").slideToggle();
+ });
+});
+
+$(document).on("click", ".docs-article-toggle-button", function () {
+ let articleToggleTitle = "Expand docstring";
+ let navArticleToggleTitle = "Expand all docstrings";
+
+ debounce(() => {
+ if (isExpanded) {
+ $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down");
+ $(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-down")
+ .addClass("fa-chevron-right");
+
+ isExpanded = false;
+
+ $(".docstring section").slideUp();
+ } else {
+ $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up");
+ $(".docstring-article-toggle-button")
+ .removeClass("fa-chevron-right")
+ .addClass("fa-chevron-down");
+
+ isExpanded = true;
+ articleToggleTitle = "Collapse docstring";
+ navArticleToggleTitle = "Collapse all docstrings";
+
+ $(".docstring section").slideDown();
+ }
+
+ $(this).prop("title", navArticleToggleTitle);
+ $(".docstring-article-toggle-button").prop("title", articleToggleTitle);
+ });
+});
+
+function debounce(callback, timeout = 300) {
+ if (Date.now() - timer > timeout) {
+ callback();
+ }
+
+ clearTimeout(timer);
+
+ timer = Date.now();
+}
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require([], function() {
+function addCopyButtonCallbacks() {
+ for (const el of document.getElementsByTagName("pre")) {
+ const button = document.createElement("button");
+ button.classList.add("copy-button", "fa-solid", "fa-copy");
+ button.setAttribute("aria-label", "Copy this code block");
+ button.setAttribute("title", "Copy");
+
+ el.appendChild(button);
+
+ const success = function () {
+ button.classList.add("success", "fa-check");
+ button.classList.remove("fa-copy");
+ };
+
+ const failure = function () {
+ button.classList.add("error", "fa-xmark");
+ button.classList.remove("fa-copy");
+ };
+
+ button.addEventListener("click", function () {
+ copyToClipboard(el.innerText).then(success, failure);
+
+ setTimeout(function () {
+ button.classList.add("fa-copy");
+ button.classList.remove("success", "fa-check", "fa-xmark");
+ }, 5000);
+ });
+ }
+}
+
+function copyToClipboard(text) {
+ // clipboard API is only available in secure contexts
+ if (window.navigator && window.navigator.clipboard) {
+ return window.navigator.clipboard.writeText(text);
+ } else {
+ return new Promise(function (resolve, reject) {
+ try {
+ const el = document.createElement("textarea");
+ el.textContent = text;
+ el.style.position = "fixed";
+ el.style.opacity = 0;
+ document.body.appendChild(el);
+ el.select();
+ document.execCommand("copy");
+
+ resolve();
+ } catch (err) {
+ reject(err);
+ } finally {
+ document.body.removeChild(el);
+ }
+ });
+ }
+}
+
+if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks);
+} else {
+ addCopyButtonCallbacks();
+}
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function () {
+ $("#documenter .docs-navbar").headroom({
+ tolerance: { up: 10, down: 10 },
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'minisearch'], function($, minisearch) {
+
+// In general, most search related things will have "search" as a prefix.
+// To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc
+
+let results = [];
+let timer = undefined;
+
+let data = documenterSearchIndex["docs"].map((x, key) => {
+ x["id"] = key; // minisearch requires a unique for each object
+ return x;
+});
+
+// list below is the lunr 2.1.3 list minus the intersect with names(Base)
+// (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+// ideally we'd just filter the original list but it's not available as a variable
+const stopWords = new Set([
+ "a",
+ "able",
+ "about",
+ "across",
+ "after",
+ "almost",
+ "also",
+ "am",
+ "among",
+ "an",
+ "and",
+ "are",
+ "as",
+ "at",
+ "be",
+ "because",
+ "been",
+ "but",
+ "by",
+ "can",
+ "cannot",
+ "could",
+ "dear",
+ "did",
+ "does",
+ "either",
+ "ever",
+ "every",
+ "from",
+ "got",
+ "had",
+ "has",
+ "have",
+ "he",
+ "her",
+ "hers",
+ "him",
+ "his",
+ "how",
+ "however",
+ "i",
+ "if",
+ "into",
+ "it",
+ "its",
+ "just",
+ "least",
+ "like",
+ "likely",
+ "may",
+ "me",
+ "might",
+ "most",
+ "must",
+ "my",
+ "neither",
+ "no",
+ "nor",
+ "not",
+ "of",
+ "off",
+ "often",
+ "on",
+ "or",
+ "other",
+ "our",
+ "own",
+ "rather",
+ "said",
+ "say",
+ "says",
+ "she",
+ "should",
+ "since",
+ "so",
+ "some",
+ "than",
+ "that",
+ "the",
+ "their",
+ "them",
+ "then",
+ "there",
+ "these",
+ "they",
+ "this",
+ "tis",
+ "to",
+ "too",
+ "twas",
+ "us",
+ "wants",
+ "was",
+ "we",
+ "were",
+ "what",
+ "when",
+ "who",
+ "whom",
+ "why",
+ "will",
+ "would",
+ "yet",
+ "you",
+ "your",
+]);
+
+let index = new minisearch({
+ fields: ["title", "text"], // fields to index for full-text search
+ storeFields: ["location", "title", "text", "category", "page"], // fields to return with search results
+ processTerm: (term) => {
+ let word = stopWords.has(term) ? null : term;
+ if (word) {
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ word = word
+ .replace(/^[^a-zA-Z0-9@!]+/, "")
+ .replace(/[^a-zA-Z0-9@!]+$/, "");
+ }
+
+ return word ?? null;
+ },
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not find anything if searching for "add!", only for the entire qualification
+ tokenize: (string) => string.split(/[\s\-\.]+/),
+ // options which will be applied during the search
+ searchOptions: {
+ boost: { title: 100 },
+ fuzzy: 2,
+ processTerm: (term) => {
+ let word = stopWords.has(term) ? null : term;
+ if (word) {
+ word = word
+ .replace(/^[^a-zA-Z0-9@!]+/, "")
+ .replace(/[^a-zA-Z0-9@!]+$/, "");
+ }
+
+ return word ?? null;
+ },
+ tokenize: (string) => string.split(/[\s\-\.]+/),
+ },
+});
+
+index.addAll(data);
+
+let filters = [...new Set(data.map((x) => x.category))];
+var modal_filters = make_modal_body_filters(filters);
+var filter_results = [];
+
+$(document).on("keyup", ".documenter-search-input", function (event) {
+ // Adding a debounce to prevent disruptions from super-speed typing!
+ debounce(() => update_search(filter_results), 300);
+});
+
+$(document).on("click", ".search-filter", function () {
+ if ($(this).hasClass("search-filter-selected")) {
+ $(this).removeClass("search-filter-selected");
+ } else {
+ $(this).addClass("search-filter-selected");
+ }
+
+ // Adding a debounce to prevent disruptions from crazy clicking!
+ debounce(() => get_filters(), 300);
+});
+
+/**
+ * A debounce function, takes a function and an optional timeout in milliseconds
+ *
+ * @function callback
+ * @param {number} timeout
+ */
+function debounce(callback, timeout = 300) {
+ clearTimeout(timer);
+ timer = setTimeout(callback, timeout);
+}
+
+/**
+ * Make/Update the search component
+ *
+ * @param {string[]} selected_filters
+ */
+function update_search(selected_filters = []) {
+ let initial_search_body = `
+
Type something to get started!
+ `;
+
+ let querystring = $(".documenter-search-input").val();
+
+ if (querystring.trim()) {
+ results = index.search(querystring, {
+ filter: (result) => {
+ // Filtering results
+ if (selected_filters.length === 0) {
+ return result.score >= 1;
+ } else {
+ return (
+ result.score >= 1 && selected_filters.includes(result.category)
+ );
+ }
+ },
+ });
+
+ let search_result_container = ``;
+ let search_divider = ``;
+
+ if (results.length) {
+ let links = [];
+ let count = 0;
+ let search_results = "";
+
+ results.forEach(function (result) {
+ if (result.location) {
+ // Checking for duplication of results for the same page
+ if (!links.includes(result.location)) {
+ search_results += make_search_result(result, querystring);
+ count++;
+ }
+
+ links.push(result.location);
+ }
+ });
+
+ let result_count = `
+ `;
+
+ return filter_html;
+}
+
+/**
+ * Make the result component given a minisearch result data object and the value of the search input as queryString.
+ * To view the result object structure, refer: https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult
+ *
+ * @param {object} result
+ * @param {string} querystring
+ * @returns string
+ */
+function make_search_result(result, querystring) {
+ let search_divider = ``;
+ let display_link =
+ result.location.slice(Math.max(0), Math.min(50, result.location.length)) +
+ (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div
+
+ if (result.page !== "") {
+ display_link += ` (${result.page})`;
+ }
+
+ let textindex = new RegExp(`\\b${querystring}\\b`, "i").exec(result.text);
+ let text =
+ textindex !== null
+ ? result.text.slice(
+ Math.max(textindex.index - 100, 0),
+ Math.min(
+ textindex.index + querystring.length + 100,
+ result.text.length
+ )
+ )
+ : ""; // cut-off text before and after from the match
+
+ let display_result = text.length
+ ? "..." +
+ text.replace(
+ new RegExp(`\\b${querystring}\\b`, "i"), // For first occurrence
+ '$&'
+ ) +
+ "..."
+ : ""; // highlights the match
+
+ let in_code = false;
+ if (!["page", "section"].includes(result.category.toLowerCase())) {
+ in_code = true;
+ }
+
+ // We encode the full url to escape some special characters which can lead to broken links
+ let result_div = `
+
+
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.
Create movies for representation of earthquake or wave propagation.
Create geodynamic input models (for LaMEM)
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
diff --git a/previews/PR67/man/LaPalma_example/index.html b/previews/PR67/man/LaPalma_example/index.html
new file mode 100644
index 00000000..512c8a59
--- /dev/null
+++ b/previews/PR67/man/LaPalma_example/index.html
@@ -0,0 +1,26 @@
+
+14 - Cartesian Volcano Model · GeophysicalModelGenerator.jl
In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of the Cumbre Viejo eruption in La Palma, which is a volcanic island that erupted from mid september 2021 - december 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.
In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:
As earthquakes are point-wise data, you have to specify this. Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where z is not pointing upwards).
In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
proj = ProjectionPoint(Lon=-17.84, Lat=28.56)
Once this is done you can convert the topographic data to the cartesian reference frame
It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:
In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command
Grid = ReadLaMEM_InputFile("LaPalma.dat")
The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.
In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celsius).
Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.
Looking at the seismicity, there is a swarm at around 35 km depth
Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.
Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory
The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
Everything that fulfills this criteria gets the number 1, everything else 0.
Do the same with other tomographic models (using the same criteria or a different one).
Make sure that all tomographic models are interpolated to the same grid.
Sum up the 3 models.
The resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
So how do we create Votemaps? Doing this is rather simple:
This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:
And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
Write_Paraview(Data_VoteMap, "VoteMap_Alps")
In paraview, this gives
You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:
Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
GeophysicalModelGenerator.jl's development is coordinated by a group of principal developers, who are also its main contributors and who can be contacted in case of questions about GeophysicalModelGenerator.jl. In addition, there are contributors who have provided substantial additions or modifications. Together, these two groups form "The GeophysicalModelGenerator.jl Authors".
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
Our Standards
Examples of behavior that contributes to a positive environment for our community include:
Demonstrating empathy and kindness toward other people
Being respectful of differing opinions, viewpoints, and experiences
Giving and gracefully accepting constructive feedback
Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
The use of sexualized language or imagery, and sexual attention or advances of any kind
Trolling, insulting or derogatory comments, and personal or political attacks
Public or private harassment
Publishing others' private information, such as a physical or email address, without their explicit permission
Other conduct which could reasonably be considered inappropriate in a professional setting
Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Boris Kaus, Marcel Thielmann, or any other of the principal developers responsible for enforcement listed in Authors. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
1. Correction
Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
2. Warning
Community Impact: A violation through a single incident or series of actions.
Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
3. Temporary Ban
Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
4. Permanent Ban
Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within the community.
Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
GeophysicalModelGenerator.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact with one of the principal developers first (see Authors).
GeophysicalModelGenerator.jl and its contributions are licensed under the MIT license. As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.
Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.
Data structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.
depth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Cartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
Data structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers
x,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
x,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.
Example
julia> x = 0:2:10
+julia> y = -5:5
+julia> z = -10:2:2
+julia> X,Y,Z = XYZGrid(x, y, z);
+julia> Data = Z
+julia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))
+CartData
+ size : (6, 11, 7)
+ x ϵ [ 0.0 km : 10.0 km]
+ y ϵ [ -5.0 km : 5.0 km]
+ z ϵ [ -10.0 km : 2.0 km]
+ fields : (:FakeData, :Data2)
+ attributes: ["note"]
CartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)
+RHO: 3D matrix with the density at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Read LaMEM processor partitioning file
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Reads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by ReadLaMEM_InputFile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
Calculates a 1D temperature profile [C] for variable thermal parameters including radiogenic heat source and linearly interpolates the temperature profile onto the box. The thermal parameters are defined in rheology and the structure of the lithosphere is define by LithosphericPhases().
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
Copyright (c) 2021 Boris Kaus, Marcel Thielmann and Authors (see Authors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
diff --git a/previews/PR67/man/listfunctions/index.html b/previews/PR67/man/listfunctions/index.html
new file mode 100644
index 00000000..1ed811ee
--- /dev/null
+++ b/previews/PR67/man/listfunctions/index.html
@@ -0,0 +1,531 @@
+
+List of functions · GeophysicalModelGenerator.jl
Creates a CartData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Example
julia> Lat = 1.0:3:10.0;
+julia> Lon = 11.0:4:20.0;
+julia> Depth = (-20:5:-10)*km;
+julia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);
+julia> Lon3D
+3×4×3 Array{Float64, 3}:
+[:, :, 1] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 2] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 3] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+julia> Lat3D
+ 3×4×3 Array{Float64, 3}:
+ [:, :, 1] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 2] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 3] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+julia> Depth3D
+ 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:
+ [:, :, 1] =
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+
+ [:, :, 2] =
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+
+ [:, :, 3] =
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+julia> Data = zeros(size(Lon3D));
+julia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))
+GeoData
+ size : (3, 4, 3)
+ lon ϵ [ 11.0 : 19.0]
+ lat ϵ [ 1.0 : 10.0]
+ depth ϵ [ -20.0 km : -10.0 km]
+ fields : (:DataFieldName,)
+ attributes: ["note"]
Creates a ParaviewData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.
Adds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models
Parameters
Phase - Phase array (consistent with Grid)
Temp - Temperature array (consistent with Grid)
Grid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)
xlim - left/right coordinates of box
ylim - front/back coordinates of box
zlim - bottom/top coordinates of box
phase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()
T - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()
Examples
Example 1) Layer with constant phase and temperature
julia> Grid = ReadLaMEM_InputFile("test_files/SaltModels.dat")
+LaMEM Grid:
+ nel : (32, 32, 32)
+ marker/cell : (3, 3, 3)
+ markers : (96, 96, 96)
+ x ϵ [-3.0 : 3.0]
+ y ϵ [-2.0 : 2.0]
+ z ϵ [-2.0 : 0.0]
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> AddLayer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> Write_Paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Example 2) Box with halfspace cooling profile
julia> Grid = ReadLaMEM_InputFile("test_files/SaltModels.dat")
+julia> Phases = zeros(Int32, size(Grid.X));
+julia> Temp = zeros(Float64, size(Grid.X));
+julia> AddLayer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())
+julia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model
+julia> Write_Paraview(Model3D,"LaMEM_ModelSetup") # Save model to paraview
+1-element Vector{String}:
+ "LaMEM_ModelSetup.vts"
Below = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Grid = CreateCartGrid(; size=(), x = nothing, z = nothing, y = nothing, extent = nothing, CharDim = nothing)
Creates a 1D, 2D or 3D cartesian grid of given size. Grid can be created by defining the size and either the extent (length) of the grid in all directions, or by defining start & end points (x,y,z). If you specify CharDim (a structure with characteristic dimensions created with GeoParams.jl), we will nondimensionalize the grd before creating the struct.
Spacing is assumed to be constant in a given direction
This can also be used for staggered grids, as we also create 1D vectors for the central points. The points you indicate in size are the corner points.
Note: since this is mostly for solid Earth geoscience applications, the second dimension is called z (vertical)
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
Creates a cross-section through a volumetric 3D dataset VolData with the data supplied in Profile. Depth_extent can be the minimum & maximum depth for vertical profiles
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
Volume data: data will be interpolated or directly extracted from the data set.
Surface data: surface data will be interpolated or directly extracted from the data set
Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS
'section_width' indicates the maximal distance within which point data will be projected to the profile
function CrossSectionPoints(P::GeoData; Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, section_width=50 )
Creates a projection of separate points (saved as a GeoData object) onto a chosen plane. Only points with a maximum distance of section_width are taken into account
Creates a cross-section through a surface (2D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
IMPORTANT: The surface to be extracted has to be given as a gridded GeoData object. It may also contain NaNs where it is not defined. Any points lying outside of the defined surface will be considered NaN.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
When both Start=(lon,lat) & End=(lon,lat) are given, one can also provide a the depth extent of the profile by providing Depthextent=(depthmin,depth_max)
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Depth_extent is an optional parameter that can indicate the depth extent over which you want to interpolate the vertical cross-section. Default is the full vertical extent of the 3D dataset
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
FlattenCrossSection(V::GeoData)
+This function takes a 3D cross section through a GeoData structure and computes the distance along the cross section for later 2D processing/plotting
+```julia-repl
+julia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);
+julia> Data = Depth*2; # some data
+julia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);
+julia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));
+julia> Data_cross = CrossSection(Data_set3D, Start=(10,30),End=(20,40))
+julia> x_profile = FlattenCrossSection(Data_cross)
+julia> Data_cross = AddField(Data_cross,"x_profile",x_profile)
+
+```
Data = GetLonLatDepthMag_QuakeML(filename::String)
Extracts longitude, latitude, depth and magnitude from a QuakeML file that has been e.g. downloaded from ISC. The data is then returned in GeoData format.
Reads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.
Interpolates a data field Original on a 2D CartData grid New. Typically used for horizontal surfaces.
Note: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by
Interpolates a 3D data set V with a projection point proj=(Lat, Lon) on a plane defined by x and y, where x and y are uniformly spaced. Returns the 2D array Surf_interp.
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
Location: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with "http".
Type: type of the dataset (Volume, Surface, Point, Screenshot)
Active: Do we want this file to be loaded or not? Optional parameter that defaults to true
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = Movie_Paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = Write_Paraview(Data, name, pvd=movie, time=itime)
+end
+Movie_Paraview(pvd=movie, Finalize=true)
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers
Example
This example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
value = ParseValue_LaMEM_InputFile(file,keyword,type; args::String=nothing)
Extracts a certain keyword from a LaMEM input file and convert it to a certain type. Optionally, you can also pass command-line arguments which will override the value read from the input file.
This uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Reads a VTR (structured grid) VTK file fname and extracts the coordinates, data arrays and names of the data. In general, this only contains a piece of the data, and one should open a *.pvtr file to retrieve the full data
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
In-place conversion of velocities in spherical velocities [Veast, Vnorth, Vup] to cartesian coordinates (for use in paraview).
NOTE: the magnitude of the vector will be the same, but the individual [Veast, Vnorth, Vup] components will not be retained correctly (as a different [x,y,z] coordinate system is used in paraview). Therefore, if you want to display or color that correctly in Paraview, you need to store these magnitudes as separate fields
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
Writes a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd
This takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the "reference" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.
Loads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by ReadLaMEM_InputFile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)
+RHO: 3D matrix with the density at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.
Writes a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = Movie_Paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = Write_Paraview(Data, name, pvd=movie, time=itime)
+end
+Movie_Paraview(pvd=movie, Finalize=true)
We have number of routines that makes it easier to read various datasets into GMG & create profiles through that data The routines provided here have the following functionality:
Read datasets (remote or local) that contains volumetric, surface, point, topograpy or screenshot data
Define a profile (horizontal, vertical) with space for (projected) data
Project earthquake (point) data onto the profile or intersect surfaces with a vertical profile (e.g., Moho data)
Loads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it
Location: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with "http".
Type: type of the dataset (Volume, Surface, Point, Screenshot)
Active: Do we want this file to be loaded or not? Optional parameter that defaults to true
This takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the "reference" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.
Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).
If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).
Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.
As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.
Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):
Whereas this is now in UTM Data (in meters), it is distorted.
Often it is more convenient to have this in CartData, which is done in a similar manner:
julia> Topo_Cart = Convert2CartData(Topo,p)
+CartData
+ size : (165, 75, 1)
+ x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]
+ y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]
+ z ϵ [ -4.9855 km : 3.123 km]
+ fields : (:Topography,)
This shows that the model is ~5600 by 3000 km.
Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
Volume data: data will be interpolated or directly extracted from the data set.
Surface data: surface data will be interpolated or directly extracted from the data set
Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS
'section_width' indicates the maximal distance within which point data will be projected to the profile
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
Below = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers
Example
This example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Point should have 1D coordinate vectors
Grid_counts is Grid but with an additional field Count that has the number of hits
Uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Grid_counts is Grid but with an additional field Count that has the number of hits
This uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded.
The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area.
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
diff --git a/previews/PR67/man/tutorial_ISC_data/index.html b/previews/PR67/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..a6fc5d29
--- /dev/null
+++ b/previews/PR67/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+9 - ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is separated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric formats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 separate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
Ideally, all data should be available in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from
Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004
Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:
# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)
+# when using the data please cite as:
+# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004
+X COORD (UTM Zone 32N) Y COORD (UTM Zone 32N) TOP (m.a.s.l) THICKNESS (m) DENSITY (Kg/m3)
+286635 4898615 -24823.2533 70418.125 3305
+286635 4918615 -25443.48901 69410.01563 3305
+286635 4938615 -28025.24511 66402.49219 3305
+286635 4958615 -32278.13135 61663.48438 3305
+286635 4978615 -35885.5625 57459.14063 3305
+286635 4998615 -37270.9812 55318.71094 3305
+286635 5018615 -36134.30481 55497.16406 3305
+286635 5038615 -34866.0697 55555.41406 3305
So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:
The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).
julia> res = ( length(unique(ns)), length(unique(ew)), 1)
+julia> EW = reshape(ew,res)
+julia> NS = reshape(ns,res)
+julia> Depth = reshape(depth,res)
+julia> T = reshape(thick,res)
+julia> Rho = reshape(rho,res)
So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is separated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
diff --git a/previews/PR67/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/previews/PR67/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..90670e34
--- /dev/null
+++ b/previews/PR67/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,84 @@
+
+2 - 3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> filename = ("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regular grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the command ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
julia> using GeophysicalModelGenerator
+Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:
Two shape files containing coastline and faults:
Vilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508
Earthquake data for two volcanic unrests, in 1983-84 and 2005-2016:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
De Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817
Travel time tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Ambient noise tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Load both the the shape (.shp) files contained in "./Geomorphology/*.shp" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:
To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates
Now let's plot earthquake data provided as text files. Start loading the data contained in "./SeismicLocations/*.txt". The first column gives us a temporal marker we can use to plot earthquakes in different periods.
Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in "./TravelTmeTomography/modvPS.dat" for both cartesian and UTM coordinates.
Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files "./NoiseTomography/*.txt". We read them consecutively in a "for" loop:
julia> list_files = glob("AmbientNoiseTomography/*.txt");
+julia> li = size(list_files, 1);
+julia> for i = 1:li
+julia> nameFile = list_files[i];
+julia> name_vts = name_vts[24:26];
+julia> data = readdlm(nameFile, '\t', Float64);
+julia> WE = data[:,1];
+julia> SN = data[:,2];
+julia> depth = data[:,3];
+julia> Vs = data[:,4];
However these models are too wide, so it is better to constrain them:
julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );
+julia> WE = WE[ind];
+julia> SN = SN[ind];
+julia> depth = depth[ind];
+julia> Vs = Vs[ind];
Also, nodes are irregular, hence we create a 3D regular UTM:
This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:
Earthquake data for the 1983-84 unrest:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
You will need to download the zipped folder containing all files from here.
Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here
Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.
julia> using DelimitedFiles, GeophysicalModelGenerator, Dates
+julia> p2 = @__FILE__;
+julia> p2last = findlast("/",p2);
+julia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);
+julia> output_path = string(p3,"/");
+julia> movie = Movie_Paraview(name=string(p3,"/TemporalSeismicity"), Initialize=true);
+julia> if isdir(string(p3,"/TemporalSeismicity"))==0
+julia> mkdir(string(p3,"/TemporalSeismicity"));
+julia> end
+
Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.
julia> data = readdlm("SeismicLocations/Seismicity_UTM_1983_1984.txt", '\t', skipstart=0, header=false);
+julia> l = length(data[:,1]);
+julia> dates = Date.(zeros(l,1))
+julia> for i = 1:l
+julia> df = DateFormat("yyyymmdd");
+julia> t1 = string("19",@sprintf("%5.o", data[i,1]));
+julia> t2 = Date(t1[1:8],df);
+julia> dates[i,1] = t2;
+julia> end
+julia> WE = data[:,2];
+julia> SN = data[:,3];
+julia> depth = data[:,4];
+julia> dates_num = dates - dates[1];
+
Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.
julia> nt = 50;
+julia> dt = Dates.Day(nt);
+julia> t = minimum(dates):dt:maximum(dates);
+julia> for itime = 1:length(t)-1
+julia> name = string(p3,"/TemporalSeismicity/", string(itime));
+julia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);
+julia> we = WE[tt];
+julia> sn = SN[tt];
+julia> Depth1 = depth[tt];
+julia> DN = dates_num[tt];
+julia> label_time = Dates.value(DN[end]);
+julia> if size(tt,1)>1
+julia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));
+julia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);
+julia> end
+julia>end
+julia>Movie_Paraview(pvd=movie, Finalize=true)
+
This tutorial has created a new TemporalSeismicity.pvd file that can be loaded in Paraview.
Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials. We have a range of tutorials that show the functionality of GeophysicalModelGenerator.jl (see sidebar). They are mostly stand-alone so it doesn't matter in which order they are executed. The input scripts for the tutorials are available under /tutorials.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.
It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:
julia> using GeophysicalModelGenerator, GLMakie
+julia> using GMT, JLD2
The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).
julia> ;
+shell> cd ~/Downloads/Zhao_etal_2016_data/
Now you can use the backspace key to return to the REPL, where we will load the data
julia> Data = JLD2.load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp");
At this stage you can look at it with
julia> Visualise(Data);
Note that this tends to take a while, the first time you do this (faster afterwards).
Let's add topography to the plot as well, which requires us to first load that:
This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.
And once we have done that, you can visualize the data in the same way:
julia> Visualise(Data_Cart, Topography=Topo_Cart)
Missing docstring.
Missing docstring for Visualise. Check Documenter's build log for details.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 29 February 2024. Using Julia version 1.9.4.
diff --git a/previews/PR67/scripts/LaPalma.dat b/previews/PR67/scripts/LaPalma.dat
new file mode 100644
index 00000000..89ae7bf0
--- /dev/null
+++ b/previews/PR67/scripts/LaPalma.dat
@@ -0,0 +1,357 @@
+# Define number of elements in x, y, z-direction
+# Negative number implies corresponding number of mesh segments
+# Data is provided in the variables seg_x, seg_y, seg_z and includes:
+# * coordinates of the delimiters between the segments (n-1 points)
+# * number of cells (n points)
+# * bias coefficients (n points)
+
+
+#===============================================================================
+# Scaling
+#===============================================================================
+
+# Geometry
+units = geo
+
+# Always in SI units!!
+unit_temperature = 500
+unit_length = 1000
+unit_viscosity = 1e19
+unit_stress = 1e9
+
+#===============================================================================
+# Time stepping parameters
+#===============================================================================
+
+ dt = 5e-4 # time step
+ dt_min = 4.5e-4 # minimum time step (declare divergence if lower value is attempted)
+ dt_max = 1e-3 # maximum time step
+ inc_dt = 1 # time step increment per time step (fraction of unit)
+ CFL = 0.5 # CFL (Courant-Friedrichs-Lewy) criterion
+ CFLMAX = 0.8 # CFL criterion for elasticity
+ nstep_ini = 0 # save output for n initial steps
+ nstep_max = 20 # maximum allowed number of steps (lower bound: time_end/dt_max)
+ nstep_out = 1 # save output every n steps
+
+#===============================================================================
+# Grid & discretization parameters
+#===============================================================================
+
+# relative geometry tolerance for grid manipulations (default 1e-9)
+
+ gtol = 1e-9
+
+# Number of cells for all segments
+ nel_x = 64
+ nel_y = 64
+ nel_z = 32
+
+# Coordinates of all segments (including start and end points)
+ coord_x = -50 50
+ coord_y = -40 40
+ coord_z = -80 15
+
+#===============================================================================
+# Free surface
+#===============================================================================
+
+ surf_use = 1 # free surface activation flag
+ surf_corr_phase = 1 # air phase ratio correction flag (due to surface position)
+ surf_level = 5 # initial level
+ surf_air_phase = 0 # phase ID of sticky air layer
+ surf_max_angle = 45.0 # maximum angle with horizon (smoothed if larger)
+ surf_topo_file = LaPalma_Topo.topo # initial topography file (redundant)
+ erosion_model = 0 # erosion model [0-none (default), 1-infinitely fast]
+ sediment_model = 0 # sedimentation model [0-none (default), 1-prescribed rate]
+
+#===============================================================================
+# Boundary conditions
+#===============================================================================
+
+# noslip = 0 0 0 0 0 0
+
+ temp_top = 0 # Temperature @ top
+ temp_bot = 1350 # Temperature @ bottom; side BC's are flux-free
+
+ # Background strain rate parameters
+# exx_num_periods = 1 # number intervals of constant strain rate (x-axis)
+# exx_strain_rates = -5e-16 # strain rates for each interval (negative=compression)
+
+ # Free surface top boundary flag
+ open_top_bound = 1
+
+#===============================================================================
+# Jacobian & residual evaluation parameters
+#===============================================================================
+
+ gravity = 0.0 0.0 -9.81 # gravity vector
+ act_temp_diff = 1 # temperature diffusion activation flag
+ #act_steady_temp = 0 # steady-state temperature initial guess activation flag
+ #steady_temp_t = 0.1 # time for (quasi-)steady-state temperature initial guess
+ #nstep_steady = 50 # number of steps for (quasi-)steady-state temperature initial guess (default = 1)
+ act_heat_rech = 0 # heat recharge activation flag
+ init_lith_pres = 1 # initial pressure with lithostatic pressure
+ init_guess = 1 # initial guess flag
+ eta_min = 1e18 # viscosity upper bound
+ eta_max = 1e23 # viscosity lower limit
+ eta_ref = 1e19 # reference viscosity (initial guess)
+ T_ref = 20 # reference temperature
+
+#===============================================================================
+# Solver options
+#===============================================================================
+
+ SolverType = multigrid # solver [direct or multigrid]
+ MGLevels = 4 # number of MG levels [default=3]
+
+#===============================================================================
+# Model setup & advection
+#===============================================================================
+
+ msetup = files
+ mark_load_file = ./markers/mdb # marker input file (extension is .xxxxxxxx.dat)
+
+ #poly_file = ../Polygons/RoundTopShort_256_128_21_09_20.bin
+ nmark_x = 3 # markers per cell in x-direction
+ nmark_y = 3 # ... y-direction
+ nmark_z = 3 # ... z-direction
+# rand_noise = 1 # random noise flag
+ advect = rk2 # advection scheme
+ interp = minmod # velocity interpolation scheme
+# stagp_a = 0.7 # STAG_P velocity interpolation parameter
+ mark_ctrl = basic # marker control type
+ nmark_lim = 16 100 # min/max number per cell
+
+#===============================================================================
+# Output
+#===============================================================================
+
+# Grid output options (output is always active)
+ out_file_name = LaPalma_test # output file name
+ out_pvd = 1 # activate writing .pvd file
+ out_phase = 1
+ out_density = 1
+ out_visc_total = 1
+ out_visc_creep = 1
+ out_visc_plast = 1
+ out_velocity = 1
+ out_pressure = 1
+ out_over_press = 1
+ out_litho_press = 1
+ out_temperature = 1
+# out_dev_stress = 1
+ out_j2_dev_stress = 1
+# out_strain_rate = 1
+ out_j2_strain_rate = 1
+ out_plast_strain = 1
+ out_plast_dissip = 1
+ out_tot_displ = 1
+ out_moment_res = 1
+ out_cont_res = 1
+ out_yield = 1
+
+# AVD phase viewer output options (requires activation)
+ out_avd = 1 # activate AVD phase output
+ out_avd_pvd = 1 # activate writing .pvd file
+ out_avd_ref = 1 # AVD grid refinement factor
+
+# free surface output
+ out_surf = 1 # activate surface output
+ out_surf_pvd = 1 # activate writing .pvd file
+ out_surf_velocity = 1
+ out_surf_topography = 1
+ out_surf_amplitude = 1
+
+
+#===============================================================================
+# ............................ Material Parameters .............................
+#===============================================================================
+
+# ------------------- Air -------------------
+
+ Name = air
+ ID = 0
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Water -------------------
+
+ Name = water
+ ID = 1
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+# ------------------- Upper Crust -------------------
+
+ Name = Crust
+ ID = 2
+ rho = 2900
+ alpha = 3e-5
+
+ # dislocation viscosity
+ #disl_prof = Plagioclase_An75-Ranalli_1995
+ #disl_prof = Wet_Quarzite-Ranalli_1995
+ disl_prof = Mafic_Granulite-Ranalli_1995
+
+
+ # Elastic parameters
+ G = 3e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+
+# ------------------- Mantle lithosphere-------------------
+
+ Name = Mantle
+ ID = 3
+ rho = 3320
+ alpha = 3e-5
+
+ # dislocation viscosity
+ disl_prof = Dry_Olivine-Ranalli_1995
+
+ # Elastic parameters
+ G = 6.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3.3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Andesite -------------------
+
+ Name = magma
+ ID = 4
+ rho = 2700
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e18
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 980
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Dacite -------------------
+
+ ID = 5
+ rho = 2575
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e19
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 800
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+# End of defining material properties for all phases ----------------------------------------
+
+
+#===============================================================================
+# PETSc options
+#===============================================================================
+
+
+# SNES
+
+ -snes_npicard 5
+ -snes_max_it 200
+ -snes_rtol 1e-6
+ -snes_atol 1e-6
+ -snes_PicardSwitchToNewton_rtol 1e-7 #-7
+ #-snes_NewtonSwitchToPicard_it 1 # number of Newton iterations after which we switch back to Picard
+# -snes_monitor
+# -snes_linesearch_monitor
+
+# Jacobian solver
+ -js_ksp_type fgmres
+ -js_ksp_monitor
+ -js_ksp_max_it 30
+ -js_ksp_rtol 1e-5
+ -js_ksp_atol 1e-6
+# -js_ksp_monitor_true_residual
+
+# -its_ksp_monitor
+# -ts_ksp_monitor
+
+# Multigrid
+ -gmg_pc_mg_galerkin
+ -gmg_pc_mg_type multiplicative
+ -gmg_pc_mg_cycle_type v
+
+ -gmg_mg_levels_ksp_type richardson
+ -gmg_mg_levels_ksp_richardson_scale 0.5
+ -gmg_mg_levels_ksp_max_it 5
+ -gmg_mg_levels_pc_type jacobi
+
+ -crs_pc_factor_mat_solver_package pastix
+
+
+
diff --git a/previews/PR67/search_index.js b/previews/PR67/search_index.js
new file mode 100644
index 00000000..dba7752f
--- /dev/null
+++ b/previews/PR67/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData\nGeophysicalModelGenerator.Screenshot_To_UTMData\nGeophysicalModelGenerator.ImportTopo\nGeophysicalModelGenerator.ImportGeoTIFF","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true, fieldname::Symbol=:colors)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_UTMData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_UTMData","text":"Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true, fieldname=:colors)\n\nDoes the same as Screenshot_To_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.ImportTopo","page":"Data Import","title":"GeophysicalModelGenerator.ImportTopo","text":"Optional routine that imports topography. It requires you to load GMT\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#7-3D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - 3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"7 - Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"7 - Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#1.-Download-data","page":"7 - Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#2.-Read-data-into-Julia","page":"7 - Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is separated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.-Reformat-the-data","page":"7 - Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.1-Load-and-plot-the-data-layout","page":"7 - Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#3.2-Interpolate-to-a-regular-grid","page":"7 - Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2));\njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2));\n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#4.-Generate-Paraview-file","page":"7 - Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,))\nGeoData\n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,)\njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#5.-Plotting-data-in-Paraview","page":"7 - Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#6.-Julia-script","page":"7 - Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"7 - Interpolate irregular 3D seismic tomography","title":"7 - Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/contributing/","page":"Contributing","title":"Contributing","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/CONTRIBUTING.md\"","category":"page"},{"location":"man/contributing/#contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"man/contributing/","page":"Contributing","title":"Contributing","text":"ContributingGeophysicalModelGenerator.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact with one of the principal developers first (see Authors).GeophysicalModelGenerator.jl and its contributions are licensed under the MIT license. As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.Developer Certificate of Origin (Version 1.1)The following text was taken from https://developercertificate.org:Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Letterman Drive\nSuite D4700\nSan Francisco, CA, 94129\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials. We have a range of tutorials that show the functionality of GeophysicalModelGenerator.jl (see sidebar). They are mostly stand-alone so it doesn't matter in which order they are executed. The input scripts for the tutorials are available under /tutorials.","category":"page"},{"location":"man/tutorial_local_Flegrei/#13-Campi-Flegrei-Volcano-Tutorial-using-cartesian-coordinates","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei Volcano Tutorial using cartesian coordinates","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#Goal","page":"13 - Campi Flegrei","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Two shape files containing coastline and faults:\nVilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508\nEarthquake data for two volcanic unrests, in 1983-84 and 2005-2016:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7\nDe Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817\nTravel time tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x\nAmbient noise tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x","category":"page"},{"location":"man/tutorial_local_Flegrei/#Steps","page":"13 - Campi Flegrei","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#1.-Download-all-data-for-region","page":"13 - Campi Flegrei","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Make sure that you are in the unzipped directory.","category":"page"},{"location":"man/tutorial_local_Flegrei/#2.-Geomorphology","page":"13 - Campi Flegrei","title":"2. Geomorphology","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Load both the the shape (.shp) files contained in \"./Geomorphology/*.shp\" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_Geomorphology)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates","category":"page"},{"location":"man/tutorial_local_Flegrei/#3.-Earthquakes","page":"13 - Campi Flegrei","title":"3. Earthquakes","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Now let's plot earthquake data provided as text files. Start loading the data contained in \"./SeismicLocations/*.txt\". The first column gives us a temporal marker we can use to plot earthquakes in different periods.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Glob, GeoStats\njulia> data_80s = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> data_00s = readdlm(\"SeismicLocations/Seismicity_UTM_2005_2016.txt\", ' ', skipstart=0, header=false);\njulia> data = vcat(data_80s,data_00s) \njulia> time = data[:,1];\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> EQ_Data_Cart = CartData(WE,SN,depth,(Depth=depth * m,Time=time * yr,));\njulia> Write_Paraview(EQ_Data_Cart, \"CF_Earthquakes_Cartesian\", PointsData=true)\njulia> EQ_Data_UTM = UTMData(WE, SN, depth, 33, true, (Depth=depth * m,Time=time * yr,));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,EQ_Data_UTM)\njulia> Write_Paraview(Data_set_UTM, \"CF_Earthquakes_UTM\", PointsData=true)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Save in paraview with both cartesian and UTM formats. The final seismicity map looks like this:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_seismicity)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"The colour scale distinguishes earthquakes of different decades. Notice the progressive migration of recent seismicity (black dots) towards East.","category":"page"},{"location":"man/tutorial_local_Flegrei/#4.-Velocity-model","page":"13 - Campi Flegrei","title":"4. Velocity model","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in \"./TravelTmeTomography/modvPS.dat\" for both cartesian and UTM coordinates.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"TravelTimeTomography/modvPS.dat\", '\\t', Float64, skipstart=0, header=false);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vp = data[:,4];\njulia> Vs = data[:,5];\njulia> VpVs = data[:,6];\njulia> resolution = (length(unique(depth)), length(unique(SN)), length(unique(WE)))\njulia> dim_perm = [3 2 1]\njulia> we = permutedims(reshape(WE, resolution), dim_perm);\njulia> sn = permutedims(reshape(SN, resolution), dim_perm);\njulia> depth = permutedims(reshape(depth, resolution), dim_perm);\njulia> Vp3d = permutedims(reshape(Vp, resolution), dim_perm);\njulia> Vs3d = permutedims(reshape(Vs, resolution), dim_perm);\njulia> Vp_Vs3d = permutedims(reshape(VpVs, resolution), dim_perm);\njulia> Data_set_Cartesian = CartData(we, sn, depth, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Write_Paraview(Data_set_Cartesian, \"CF_Velocity_Cartesian\")\njulia> Data_set = UTMData(we, sn, depth, 33, true, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,Data_set)\njulia> Write_Paraview(Data_set_UTM, \"CF_Velocity_UTM\")","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Including the Vp/Vs model in the previous Paraview file workspace:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_VpVs)","category":"page"},{"location":"man/tutorial_local_Flegrei/#5.-Horizontal-slices-of-shear-velocity-on-irregular-grid","page":"13 - Campi Flegrei","title":"5. Horizontal slices of shear velocity on irregular grid","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files \"./NoiseTomography/*.txt\". We read them consecutively in a \"for\" loop:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"julia> list_files = glob(\"AmbientNoiseTomography/*.txt\");\njulia> li = size(list_files, 1);\njulia> for i = 1:li\njulia> nameFile = list_files[i];\njulia> name_vts = name_vts[24:26];\njulia> data = readdlm(nameFile, '\\t', Float64);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"However these models are too wide, so it is better to constrain them:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );\njulia> WE = WE[ind];\njulia> SN = SN[ind];\njulia> depth = depth[ind];\njulia> Vs = Vs[ind];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"Also, nodes are irregular, hence we create a 3D regular UTM:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"julia> l = length(WE);\njulia> n_WE = minimum(WE):100:maximum(WE);\njulia> n_SN = minimum(SN):100:maximum(SN);\njulia> we, sn, Depth = XYZGrid(n_WE, n_SN, depth[1]);\njulia> Vs_3D = zeros(size(Depth));\njulia> Cgrid = GeoStats.CartesianGrid((size(we, 1), size(we, 2)), (minimum(we), minimum(sn)), (we[2,2,1] - we[1,1,1], sn[2,2,1] - sn[1,1,1]))\njulia> coord = PointSet([WE[:]'; SN[:]']);\njulia> Geo = georef((Vs = Vs[:],), coord);\njulia> P = EstimationProblem(Geo, Cgrid, :Vs);\njulia> S = IDW(:Vs => (;neighbors=2));\njulia> sol = solve(P, S);\njulia> sol_Vs = values(sol).Vs;\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)));\njulia> Vs_3D[:,:,1] = Vs_2D;\njulia> Data_set_Cart = CartData(we, sn, Depth, (Vs = Vs_3D * (km / s),))\njulia> Write_Paraview(Data_set_Cart, \"CF_Noise\" * name_vts * \"_Cartesian\")\njulia> Data_set = UTMData(we, sn, Depth, 33, true, (Vs = Vs_3D*(km / s),));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData, Data_set);\njulia> Write_Paraview(Data_set_UTM, \"CF_Noise_UTM_\"*name_vts)\njulia> end","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"This is one of the horizontal sections created by the code in the previous model in both reference systems:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"(Image: Tutorial_Flegrei_Noise)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"13 - Campi Flegrei","title":"13 - Campi Flegrei","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.InterpolateTopographyOnPlane\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!\nGeophysicalModelGenerator.PointData2NearestGrid\nGeophysicalModelGenerator.Convert2UTMzone\nGeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.DrapeOnTopo\nGeophysicalModelGenerator.LithostaticPressure!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)\n\nCreates a cross-section through a GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nDepending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\nVolume data: data will be interpolated or directly extracted from the data set.\nSurface data: surface data will be interpolated or directly extracted from the data set\nPoint data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\nInterpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS\n'section_width' indicates the maximal distance within which point data will be projected to the profile\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\nExtractSubvolume(V::CartData; Interpolate=false, X_level=nothing, Y_level=nothing, Z_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n2D Example along a cross-section through 3D data:\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,-300:25:0);\njulia> Data = Z.*2\njulia> Data_Int = Int64.(Data)\njulia> DataSet_Cart = CartData(X,Y,Z,(Data=Data,Data_Int=Data_Int, Velocity=(X,Y,Z)))\n\njulia> Data_cross = CrossSection(DataSet_Cart, Start=(11.0,35), End=(19, 39.0))\nCartData\n size : (100, 100, 1)\n x ϵ [ 11.0 : 19.0]\n y ϵ [ 35.0 : 39.0]\n z ϵ [ -300.0 : 0.0]\n fields : (:Data, :Data_Int, :Velocity, :FlatCrossSection)\n attributes: [\"note\"]\n\njulia> Data_extracted = ExtractSubvolume(Data_cross, X_level=(1,7), Z_level=(-200,-100))\n CartData\n size : (50, 50, 1)\n x ϵ [ 11.894427190999917 : 17.260990336999413]\n y ϵ [ 35.44721359549995 : 38.130495168499706]\n z ϵ [ -200.0 : -100.0]\n fields : (:FlatCrossSection, :Data, :Data_Int, :Velocity)\n attributes: [\"note\"]\njulia> typeof(Data_extracted.fields.Data_Int)\n Array{Int64, 3}\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"Data_interp = InterpolateDataFields(V::AbstractGeneralGrid, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set1= CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\njulia> X,Y,Z = XYZGrid(0:4:10, -1:.1:1, -5:.1:1 );\njulia> Data_set2= InterpolateDataFields(Data_set1, X,Y,Z)\n\n\n\n\n\nInterpolateDataFields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values.\n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData\n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData\n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2;\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km);\njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho);\n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Grid::CartGrid, DataSurface_Cart::CartData; above=true)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf.\n\nExample\n\njulia> Data\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n ParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.PointData2NearestGrid","page":"Tools","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"Grid_counts = PointData2NearestGrid(Point::CartData, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = PointData2NearestGrid(pt_x,pt_y,pt_z, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = PointData2NearestGrid(Point::GeoData, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\nGrid_counts = PointData2NearestGrid(pt_x,pt_y,pt_z, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\ncount = PointData2NearestGrid(pt_x,pt_y,pt_z, X,Y,Z; radius_factor=1)\n\nThis uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.Convert2UTMzone","page":"Tools","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\nConvert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.Convert2CartData","page":"Tools","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\nConvert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ProjectCartData","page":"Tools","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = ProjectCartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.DrapeOnTopo","page":"Tools","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"Topo = DrapeOnTopo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo\n\n\n\n\n\nDrapeOnTopo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.LithostaticPressure!","page":"Tools","title":"GeophysicalModelGenerator.LithostaticPressure!","text":"LithostaticPressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#3-Moho-topography","page":"3 - Visualize Moho topography","title":"3 - Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"3 - Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"3 - Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#1.-Download-data","page":"3 - Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 separate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#2.-Read-data-into-Julia","page":"3 - Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#3.-Reformat-the-data","page":"3 - Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData\n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true)\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#3.1-Fitting-a-mesh-through-the-data","page":"3 - Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Next, we define a regular lon/lat grid","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\")","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#4.-Julia-script","page":"3 - Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"3 - Visualize Moho topography","title":"3 - Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#8-Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"8 - ETOPO1 Topography and geological maps","title":"8 - Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"8 - ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"8 - ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#1.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"8 - ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#2.-Create-a-tectonic-map-with-orthogonal-projection","page":"8 - ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#3.-Import-data-to-paraview","page":"8 - ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max], grid=true);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#4.-Save","page":"8 - ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"8 - ETOPO1 Topography and geological maps","title":"8 - ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#1-3D-tomography-model-in-CSV-formation","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"1 - 3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"1 - 3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#1.-Download-data","page":"1 - 3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#2.-Read-data-into-Julia","page":"1 - 3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#3.-Reformat-the-data","page":"1 - 3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#3.1-Reshape-data-and-save-to-paraview","page":"1 - 3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#4.-Plotting-data-in-Paraview","page":"1 - 3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#5.-Extract-and-plot-cross-sections-of-the-data","page":"1 - 3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#6.-Extract-a-(3D)-subset-of-the-data","page":"1 - 3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Load-and-save-data-to-disk","page":"1 - 3D seismic tomography from ASCII","title":"Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Julia-script","page":"1 - 3D seismic tomography from ASCII","title":"Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"1 - 3D seismic tomography from ASCII","title":"1 - 3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"UTMData\nParaviewData\nCartData\nLonLatDepthGrid\nXYZGrid\nProjectionPoint","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.UTMData","page":"Data Structures","title":"GeophysicalModelGenerator.UTMData","text":"UTMData(EW::Any, NS:Any, depth::GeoUnit, UTMZone::Int, NorthernHemisphere=true, fields::NamedTuple)\n\nData structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.\n\ndepth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> ew = 422123.0:100:433623.0\njulia> ns = 4.514137e6:100:4.523637e6\njulia> depth = -5400:250:600\njulia> EW,NS,Depth = XYZGrid(ew, ns, depth);\njulia> Data = ustrip.(Depth);\njulia> Data_set = UTMData(EW,NS,Depth,33, true, (FakeData=Data,Data2=Data.+1.))\nUTMData\n UTM zone : 33-33 North\n size : (116, 96, 25)\n EW ϵ [ 422123.0 : 433623.0]\n NS ϵ [ 4.514137e6 : 4.523637e6]\n depth ϵ [ -5400.0 m : 600.0 m]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nIf you wish, you can convert this from UTMData to GeoData with\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData\n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nwhich would allow visualizing this in paraview in the usual manner:\n\njulia> Write_Paraview(Data_set1, \"Data_set1\")\n1-element Vector{String}:\n \"Data_set1.vts\"\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.ParaviewData","page":"Data Structures","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),))\njulia> Data_cart = convert(ParaviewData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::Any, y::Any, z::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers\n\nx,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nx,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nCartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with\n\njulia> Write_Paraview(Data_set, \"Data_set\")\n1-element Vector{String}:\n \"Data_set.vts\"\n\nIf you wish, you can convert this to UTMData (which will simply convert the )\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData\n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields: (:FakeData, :Data2)\n\nwhich would allow visualizing this in paraview in the usual manner:\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.ProjectionPoint","page":"Data Structures","title":"GeophysicalModelGenerator.ProjectionPoint","text":"struct ProjectionPoint\n Lon :: Float64\n Lat :: Float64\n EW :: Float64\n NS :: Float64\n zone :: Integer\n isnorth :: Bool\nend\n\nStructure that holds the coordinates of a point that is used to project a data set from Lon/Lat to a Cartesian grid and vice-versa.\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeoData","category":"page"},{"location":"man/tutorial_time_Seismicity/#15-How-to-create-a-movie-that-shows-the-temporal-evolution-of-seismicity","page":"15 - Create movies","title":"15 - How to create a movie that shows the temporal evolution of seismicity","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#Goal","page":"15 - Create movies","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Earthquake data for the 1983-84 unrest:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7","category":"page"},{"location":"man/tutorial_time_Seismicity/#Steps","page":"15 - Create movies","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#1.-Download-all-data-for-region","page":"15 - Create movies","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"(Image: Tutorial_SeismicTime_1)","category":"page"},{"location":"man/tutorial_time_Seismicity/#2.-Earthquakes-in-movie","page":"15 - Create movies","title":"2. Earthquakes in movie","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Dates\njulia> p2 = @__FILE__;\njulia> p2last = findlast(\"/\",p2);\njulia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);\njulia> output_path = string(p3,\"/\");\njulia> movie = Movie_Paraview(name=string(p3,\"/TemporalSeismicity\"), Initialize=true);\njulia> if isdir(string(p3,\"/TemporalSeismicity\"))==0\njulia> mkdir(string(p3,\"/TemporalSeismicity\"));\njulia> end\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"julia> data = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> l = length(data[:,1]);\njulia> dates = Date.(zeros(l,1))\njulia> for i = 1:l\njulia> df = DateFormat(\"yyyymmdd\");\njulia> t1 = string(\"19\",@sprintf(\"%5.o\", data[i,1]));\njulia> t2 = Date(t1[1:8],df);\njulia> dates[i,1] = t2;\njulia> end\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> dates_num = dates - dates[1];\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"julia> nt = 50;\njulia> dt = Dates.Day(nt);\njulia> t = minimum(dates):dt:maximum(dates);\njulia> for itime = 1:length(t)-1\njulia> name = string(p3,\"/TemporalSeismicity/\", string(itime));\njulia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);\njulia> we = WE[tt];\njulia> sn = SN[tt];\njulia> Depth1 = depth[tt];\njulia> DN = dates_num[tt];\njulia> label_time = Dates.value(DN[end]);\njulia> if size(tt,1)>1\njulia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));\njulia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);\njulia> end\njulia>end\njulia>Movie_Paraview(pvd=movie, Finalize=true)\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"This tutorial has created a new TemporalSeismicity.pvd file that can be loaded in Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"(Image: Tutorial_SeismicTime_PVD)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"(Image: Tutorial_SeismicTime_Movie)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"15 - Create movies","title":"15 - Create movies","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/authors/#Authors","page":"Authors","title":"Authors","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"GeophysicalModelGenerator.jl's development is coordinated by a group of principal developers, who are also its main contributors and who can be contacted in case of questions about GeophysicalModelGenerator.jl. In addition, there are contributors who have provided substantial additions or modifications. Together, these two groups form \"The GeophysicalModelGenerator.jl Authors\".","category":"page"},{"location":"man/authors/#Principal-Developers","page":"Authors","title":"Principal Developers","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"Boris Kaus, Johannes Gutenberg University Mainz, Germany\nMarcel Thielmann, Bayerisches Geoinstitut, University of Bayreuth, Germany","category":"page"},{"location":"man/authors/#Contributors","page":"Authors","title":"Contributors","text":"","category":"section"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"The following people contributed major additions or modifications to GeophysicalModelGenerator.jl and are listed in alphabetical order:","category":"page"},{"location":"man/authors/","page":"Authors","title":"Authors","text":"Pascal Aellig\nLuca De Siena\nAndrea Piccolo\nHendrik Rachona\nChristian Schuler\nArne Spang\nTatjana Weiler","category":"page"},{"location":"man/code_of_conduct/","page":"Code of Conduct","title":"Code of Conduct","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/CODE_OF_CONDUCT.md\"","category":"page"},{"location":"man/code_of_conduct/#code-of-conduct","page":"Code of Conduct","title":"Code of Conduct","text":"","category":"section"},{"location":"man/code_of_conduct/","page":"Code of Conduct","title":"Code of Conduct","text":"Contributor Covenant Code of ConductOur PledgeWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.Our StandardsExamples of behavior that contributes to a positive environment for our community include:Demonstrating empathy and kindness toward other people\nBeing respectful of differing opinions, viewpoints, and experiences\nGiving and gracefully accepting constructive feedback\nAccepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\nFocusing on what is best not just for us as individuals, but for the overall communityExamples of unacceptable behavior include:The use of sexualized language or imagery, and sexual attention or advances of any kind\nTrolling, insulting or derogatory comments, and personal or political attacks\nPublic or private harassment\nPublishing others' private information, such as a physical or email address, without their explicit permission\nOther conduct which could reasonably be considered inappropriate in a professional settingEnforcement ResponsibilitiesCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.ScopeThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.EnforcementInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to Boris Kaus, Marcel Thielmann, or any other of the principal developers responsible for enforcement listed in Authors. All complaints will be reviewed and investigated promptly and fairly.All community leaders are obligated to respect the privacy and security of the reporter of any incident.Enforcement GuidelinesCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:1. CorrectionCommunity Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.2. WarningCommunity Impact: A violation through a single incident or series of actions.Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.3. Temporary BanCommunity Impact: A serious violation of community standards, including sustained inappropriate behavior.Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.4. Permanent BanCommunity Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.Consequence: A permanent ban from any sort of public interaction within the community.AttributionThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.[homepage]: https://www.contributor-covenant.orgFor answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#6-Import-profiles/maps-from-published-papers","page":"6 - Import screenshots","title":"6 - Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"6 - Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Ideally, all data should be available in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Here, we explain how.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"6 - Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section \\& create VTS file\n3. Read data of a mapview \\& create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"6 - Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#1.-Download-data-and-crop-images","page":"6 - Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#2.-Read-data-of-a-cross-section-and-create-VTS-file","page":"6 - Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"julia> Corner_LowerLeft = ( 4.65, 45.73, -400.0)\njulia> Corner_UpperRight = (17.23, 43.80, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = (4.65 , 45.73 , -400.0 )\n └ lower right = (17.23 , 43.8 , -400.0 )\n └ upper left = (4.65 , 45.73 , 0.0 )\n └ upper right = (17.23 , 43.8 , 0.0 )\nGeoData\n size : (325, 824, 1)\n lon ϵ [ 4.6499999999999995 : 17.230000000000004]\n lat ϵ [ 43.79999999999999 : 45.730000000000004]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\")","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#3.-Read-data-of-a-mapview-and-create-*.vts-file","page":"6 - Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\")","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#4.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"6 - Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#5.-Creating-a-multiblock-Paraview/*.vtm-file","page":"6 - Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile)\njulia> Write_Paraview(data_Fig12_180km, vtmfile)\njulia> Write_Paraview(data_Fig12_300km, vtmfile)\njulia> Write_Paraview(data_Fig12_400km, vtmfile)\njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#6.-Julia-script","page":"6 - Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"6 - Import screenshots","title":"6 - Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/profile_processing/#Profile-processing","page":"Profile Processing","title":"Profile processing","text":"","category":"section"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"We have number of routines that makes it easier to read various datasets into GMG & create profiles through that data The routines provided here have the following functionality:","category":"page"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"Read datasets (remote or local) that contains volumetric, surface, point, topograpy or screenshot data\nDefine a profile (horizontal, vertical) with space for (projected) data\nProject earthquake (point) data onto the profile or intersect surfaces with a vertical profile (e.g., Moho data)","category":"page"},{"location":"man/profile_processing/","page":"Profile Processing","title":"Profile Processing","text":"GeophysicalModelGenerator.load_GMG\nGeophysicalModelGenerator.save_GMG\nGeophysicalModelGenerator.ProfileData\nGeophysicalModelGenerator.ExtractProfileData\nGeophysicalModelGenerator.CreateProfileData\nGeophysicalModelGenerator.GMG_Dataset\nGeophysicalModelGenerator.Load_Dataset_file\nGeophysicalModelGenerator.combine_VolData\nGeophysicalModelGenerator.ExtractProfileData!\nGeophysicalModelGenerator.ReadPickedProfiles","category":"page"},{"location":"man/profile_processing/#GeophysicalModelGenerator.load_GMG","page":"Profile Processing","title":"GeophysicalModelGenerator.load_GMG","text":"data::NamedTuple = load_GMG(data::GMG_Dataset)\n\nLoads a dataset specified in GMG_Dataset data and returns it as a named tuple\n\n\n\n\n\nData = load_GMG(Datasets::Vector{GMG_Dataset})\n\nThis loads all the active datasets in Datasets, and returns a NamedTuple with Volume, Surface, Point, Screenshot and Topography data\n\n\n\n\n\nload_GMG(filename::String, dir=pwd())\n\nLoads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it\n\nExample 1 - Load local file\n\njulia> data = load_GMG(\"test\")\nGeoData \n size : (4, 3, 3)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 19.0]\n depth ϵ [ -20.0 : -10.0]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\nExample 2 - remote download\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\"\njulia> load_GMG(url)\nGeoData \n size : (149, 242, 1)\n lon ϵ [ -24.875 : 35.375]\n lat ϵ [ 34.375 : 71.375]\n depth ϵ [ -11.76 : -34.7]\n fields : (:MohoDepth,)\n attributes: [\"author\", \"year\"]\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.save_GMG","page":"Profile Processing","title":"GeophysicalModelGenerator.save_GMG","text":"save_GMG(filename::String, data::Union{GeoData, CartDat, UTMData}; dir=pwd())\n\nSaves the dataset data to a JLD2 file (name without extension) in the directory dir\n\nExample\n\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(1.0:3:10.0, 11.0:4:20.0, (-20:5:-10)*km);\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Depth3D,)) \njulia> save_GMG(\"test\",Data_set)\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.ExtractProfileData","page":"Profile Processing","title":"GeophysicalModelGenerator.ExtractProfileData","text":"ExtractProfileData(ProfileCoordFile::String,ProfileNumber::Int64,DataSetFile::String; DimsVolCross=(100,100),DepthVol=nothing,DimsSurfCross=(100,),WidthPointProfile=50km)\n\nThis is a convenience function (mostly for backwards compatibility with the MATLAB GUI) that loads the data from file & projects it onto a profile\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.Load_Dataset_file","page":"Profile Processing","title":"GeophysicalModelGenerator.Load_Dataset_file","text":"Datasets = Load_Dataset_file(file_datasets::String)\n\nThis loads a CSV textfile that lists datasets, which is expected to have the following format:\n\nName,Location,Type, [Active]\nAlpArray,./Seismicity/ALPARRAY/AlpArraySeis.jld2,Point, true\nPlomerova2022,https://seafile.rlp.net/f/abccb8d3302b4ef5af17/?dl=1,Volume\n\nNote that the first line of the file is skipped.\n\nHere, the meaning of the variables is:\n\nName: The name of the dataset to be loaded\nLocation: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with \"http\".\nType: type of the dataset (Volume, Surface, Point, Screenshot)\nActive: Do we want this file to be loaded or not? Optional parameter that defaults to true\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.combine_VolData","page":"Profile Processing","title":"GeophysicalModelGenerator.combine_VolData","text":"VolData_combined = combine_VolData(VolData::NamedTuple; lat=nothing, lon=nothing, depth=nothing, dims=(100,100,100), dataset_preferred = 1)\n\nThis takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the \"reference\" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.ExtractProfileData!","page":"Profile Processing","title":"GeophysicalModelGenerator.ExtractProfileData!","text":"ExtractProfileData!(Profile::ProfileData,VolData::GeoData, SurfData::NamedTuple, PointData::NamedTuple; DimsVolCross=(100,100),Depth_extent=nothing,DimsSurfCross=(100,),section_width=50)\n\nExtracts data along a vertical or horizontal profile\n\n\n\n\n\n","category":"function"},{"location":"man/profile_processing/#GeophysicalModelGenerator.ReadPickedProfiles","page":"Profile Processing","title":"GeophysicalModelGenerator.ReadPickedProfiles","text":"This reads the picked profiles from disk and returns a vector of ProfileData\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"Here an overview of all functions:","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"Modules = [GeophysicalModelGenerator]","category":"page"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{CartGrid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"Data = CartData(Grid::CartGrid, fields::NamedTuple; y_val=0.0)\n\nReturns a CartData set given a cartesian grid Grid and fields defined on that grid.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{LaMEM_grid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"CartData(Grid::LaMEM_grid, fields::NamedTuple)\n\nCreates a CartData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartData-Tuple{Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.CartData","text":"CartData(xyz::Tuple{Array,Array,Array})\n\nThis creates a CartData struct if you have a Tuple with 3D coordinates as input.\n\nExample\n\njulia> data = CartData(XYZGrid(-10:10,-5:5,0))\nCartData\n size : (21, 11, 1)\n x ϵ [ -10.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CartGrid","page":"List of functions","title":"GeophysicalModelGenerator.CartGrid","text":"Structure that holds data for an orthogonal cartesian grid, which can be described with 1D vectors\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GMG_Dataset","page":"List of functions","title":"GeophysicalModelGenerator.GMG_Dataset","text":"Structure that stores info about a GMG Dataset, which is useful to collect a wide variety of datasets.\n\nName :: String # Name of the dataset\nType :: String # Volumetric, Surface, Point, Screenshot\nDirName :: String # Directory name or url of dataset\nactive :: Bool # should this data be loaded or not?\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GeoData","page":"List of functions","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields.\nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.\nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> Lat = 1.0:3:10.0;\njulia> Lon = 11.0:4:20.0;\njulia> Depth = (-20:5:-10)*km;\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);\njulia> Lon3D\n3×4×3 Array{Float64, 3}:\n[:, :, 1] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 2] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 3] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\njulia> Lat3D\n 3×4×3 Array{Float64, 3}:\n [:, :, 1] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n\n [:, :, 2] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n\n [:, :, 3] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\njulia> Depth3D\n 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:\n [:, :, 1] =\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n\n [:, :, 2] =\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n\n [:, :, 3] =\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\njulia> Data = zeros(size(Lon3D));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))\nGeoData\n size : (3, 4, 3)\n lon ϵ [ 11.0 : 19.0]\n lat ϵ [ 1.0 : 10.0]\n depth ϵ [ -20.0 km : -10.0 km]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParaviewData-Tuple{LaMEM_grid, NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(Grid::LaMEM_grid, fields::NamedTuple)\n\nCreates a ParaviewData struct from a LaMEM grid and from fields stored on that grid. Note that one needs to have a field Phases and optionally a field Temp to create LaMEM marker files.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProfileData","page":"List of functions","title":"GeophysicalModelGenerator.ProfileData","text":"Structure that holds profile data (interpolated/projected on the profile)\n\nstruct ProfileData\n vertical :: Bool # vertical:true, horizontal:false\n start_lonlat :: Union{Nothing,Tuple{Float64,Float64}}\n end_lonlat :: Union{Nothing,Tuple{Float64,Float64}}\n depth :: Union{Nothing,Float64}\n VolData :: GeophysicalModelGenerator.GeoData\n SurfData :: Union{Nothing, NamedTuple}\n PointData :: Union{Nothing, NamedTuple}\nend\n\nStructure to store cross section data\n\n\n\n\n\n","category":"type"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectionPoint-Tuple{Float64, Float64, Int64, Bool}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectionPoint","text":"ProjectionPoint(EW::Float64, NS::Float64, Zone::Int64, isnorth::Bool)\n\nDefines a projection point used for map projections, by specifying UTM coordinates (EW/NS), UTM Zone and whether you are on the northern hemisphere\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectionPoint-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectionPoint","text":"ProjectionPoint(; Lat=49.9929, Lon=8.2473)\n\nDefines a projection point used for map projections, by specifying latitude and longitude\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#Base.convert-Tuple{Type{GeoData}, UTMData}","page":"List of functions","title":"Base.convert","text":"Converts a UTMData structure to a GeoData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#Base.convert-Tuple{Type{UTMData}, GeoData}","page":"List of functions","title":"Base.convert","text":"Converts a GeoData structure to a UTMData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AboveSurface-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.AboveSurface","text":"Above = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AboveSurface-Tuple{CartGrid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.AboveSurface","text":"Above = AboveSurface(Grid::CartGrid, DataSurface_Cart::CartData; above=true)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AboveSurface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2;\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km);\njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho);\n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AboveSurface-Tuple{LaMEM_grid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.AboveSurface","text":"Above = AboveSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AboveSurface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.AboveSurface","text":"Above = AboveSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddBox!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddCylinder!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.AddCylinder!","text":"AddCylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base=Tuple{3}, cap=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddCylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddEllipsoid!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.AddEllipsoid!","text":"AddEllipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, axes=Tuple{3},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddEllipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddField-Tuple{AbstractGeneralGrid, String, Any}","page":"List of functions","title":"GeophysicalModelGenerator.AddField","text":"V = AddField(V::AbstractGeneralGrid,field_name::String,data::Any)\n\nAdd Fields Data to GeoData or CartData\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddLayer!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.AddLayer!","text":"AddLayer!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a layer with phase & temperature structure to a 3D model setup. The most common use would be to add a lithospheric layer to a model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box\nzlim - bottom/top coordinates of box\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExamples\n\nExample 1) Layer with constant phase and temperature\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddLayer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddLayer!(Phases,Temp,Grid, zlim=(-50,0), phase=ConstantPhase(3), T=HalfspaceCoolingTemp())\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddSphere!-Tuple{Any, Any, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.AddSphere!","text":"AddSphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddSphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddSurfaces!-Tuple{Union{CartData, ParaviewData}, Union{CartData, ParaviewData}}","page":"List of functions","title":"GeophysicalModelGenerator.AddSurfaces!","text":"AddSurfaces!(Surface1::Union{CartData,ParaviewData}, Surface2::Union{CartData,ParaviewData})\n\nAdds Surface2 to Surface1. The addition happens on the Surface1.z; the fields remain unchanged\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.AddSurfaces!-Tuple{Union{GeoData, UTMData}, Union{GeoData, UTMData}}","page":"List of functions","title":"GeophysicalModelGenerator.AddSurfaces!","text":"AddSurfaces!(Surface1::Union{GeoData,UTMData}, Surface2::Union{GeoData,UTMData})\n\nAdds Surface2 to Surface1. The addition happens on the Surface1.depth; the fields remain unchanged\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.BelowSurface-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.BelowSurface-Tuple{CartGrid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.BelowSurface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.BelowSurface-Tuple{LaMEM_grid, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.BelowSurface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Compute_Phase-Tuple{Any, Any, Any, Any, Any, LithosphericPhases}","page":"List of functions","title":"GeophysicalModelGenerator.Compute_Phase","text":"Phase = Compute_Phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = Compute_Phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Convert2CartData-Tuple{GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Convert2CartData-Tuple{UTMData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Convert2UTMzone-Tuple{CartData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Convert2UTMzone-Tuple{GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Create1D_grid_vector-Tuple{Vector{Float64}, Int64, Int64, Union{Nothing, Int64}, Union{Nothing, Float64}}","page":"List of functions","title":"GeophysicalModelGenerator.Create1D_grid_vector","text":"Returns 1D coordinate vectors of grid points and of marker locations for a regular spacing\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Create1D_grid_vector-Union{Tuple{I}, Tuple{T}, Tuple{Vector{T}, Vector{I}, I, I, Union{Nothing, Vector{T}, T}}} where {T<:Float64, I<:Int64}","page":"List of functions","title":"GeophysicalModelGenerator.Create1D_grid_vector","text":"Returns 1D coordinate vectors of grid points and of marker locations for a regular spacing\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CreateCartGrid-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.CreateCartGrid","text":"Grid = CreateCartGrid(; size=(), x = nothing, z = nothing, y = nothing, extent = nothing, CharDim = nothing)\n\nCreates a 1D, 2D or 3D cartesian grid of given size. Grid can be created by defining the size and either the extent (length) of the grid in all directions, or by defining start & end points (x,y,z). If you specify CharDim (a structure with characteristic dimensions created with GeoParams.jl), we will nondimensionalize the grd before creating the struct.\n\nSpacing is assumed to be constant in a given direction\n\nThis can also be used for staggered grids, as we also create 1D vectors for the central points. The points you indicate in size are the corner points.\n\nNote: since this is mostly for solid Earth geoscience applications, the second dimension is called z (vertical)\n\nExamples\n\n====\n\nA basic case with non-dimensional units:\n\njulia> Grid = CreateCartGrid(size=(10,20),x=(0.,10), z=(2.,10))\nGrid{Float64, 2}\n size: (10, 20)\n length: (10.0, 8.0)\n domain: x ∈ [0.0, 10.0], z ∈ [2.0, 10.0]\n grid spacing Δ: (1.1111111111111112, 0.42105263157894735)\n\nAn example with dimensional units:\n\njulia> CharDim = GEO_units()\njulia> Grid = CreateCartGrid(size=(10,20),x=(0.0km, 10km), z=(-20km, 10km), CharDim=CharDim)\nCartGrid{Float64, 2}\n size: (10, 20)\n length: (0.01, 0.03)\n domain: x ∈ [0.0, 0.01], z ∈ [-0.02, 0.01]\n grid spacing Δ: (0.0011111111111111111, 0.0015789473684210528)\n\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CreatePartitioningFile-Tuple{String, Int64}","page":"List of functions","title":"GeophysicalModelGenerator.CreatePartitioningFile","text":"CreatePartitioningFile(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\", verbose=true)\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CreateProfileVolume!-Tuple{ProfileData, AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.CreateProfileVolume!","text":"CreateProfileVolume!(Profile::ProfileData, VolData::AbstractGeneralGrid; DimsVolCross::NTuple=(100,100), Depth_extent=nothing)\n\nCreates a cross-section through a volumetric 3D dataset VolData with the data supplied in Profile. Depth_extent can be the minimum & maximum depth for vertical profiles\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CrossSection-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(DataSet::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, Depth_extent=nothing, section_width=50km)\n\nCreates a cross-section through a GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nDepending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\nVolume data: data will be interpolated or directly extracted from the data set.\nSurface data: surface data will be interpolated or directly extracted from the data set\nPoint data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\nInterpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC AND SURFACE DATA SETS\n'section_width' indicates the maximal distance within which point data will be projected to the profile\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CrossSectionPoints-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.CrossSectionPoints","text":"function CrossSectionPoints(P::GeoData; Depth_level=nothing, Lat_level=nothing, Lon_level=nothing, Start=nothing, End=nothing, section_width=50 )\n\nCreates a projection of separate points (saved as a GeoData object) onto a chosen plane. Only points with a maximum distance of section_width are taken into account\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CrossSectionSurface-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.CrossSectionSurface","text":"CrossSectionSurface(Surface::GeoData; dims=(100,), Interpolate=false, Depthlevel=nothing; Latlevel=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a surface (2D) GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nIMPORTANT: The surface to be extracted has to be given as a gridded GeoData object. It may also contain NaNs where it is not defined. Any points lying outside of the defined surface will be considered NaN.\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set2D = GeoData(Lon,Lat,Depth,(Depth=Depth,));\njulia> Data_cross = CrossSectionSurface(Data_set2D, Lat_level =15)\nGeoData\n size : (100,)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 15.0 : 15.0]\n depth ϵ [ NaN : NaN]\n fields : (:Depth,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.CrossSectionVolume-Tuple{AbstractGeneralGrid}","page":"List of functions","title":"GeophysicalModelGenerator.CrossSectionVolume","text":"CrossSectionVolume(Volume::AbstractGeneralGrid; dims=(100,100), Interpolate=false, Depthlevel=nothing; Latlevel=nothing; Lonlevel=nothing; Start=nothing, End=nothing, Depthextent=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object.\n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nWhen both Start=(lon,lat) & End=(lon,lat) are given, one can also provide a the depth extent of the profile by providing Depthextent=(depthmin,depth_max)\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\nDepth_extent is an optional parameter that can indicate the depth extent over which you want to interpolate the vertical cross-section. Default is the full vertical extent of the 3D dataset\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = CrossSectionVolume(Data_set3D, Depth_level=-100km)\nGeoData\n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.DrapeOnTopo-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"DrapeOnTopo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.DrapeOnTopo-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"Topo = DrapeOnTopo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ExtractProfileData!","page":"List of functions","title":"GeophysicalModelGenerator.ExtractProfileData!","text":"ExtractProfileData!(Profile::ProfileData,VolData::GeoData, SurfData::NamedTuple, PointData::NamedTuple; DimsVolCross=(100,100),Depth_extent=nothing,DimsSurfCross=(100,),section_width=50)\n\nExtracts data along a vertical or horizontal profile\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ExtractProfileData-Tuple{String, Int64, String}","page":"List of functions","title":"GeophysicalModelGenerator.ExtractProfileData","text":"ExtractProfileData(ProfileCoordFile::String,ProfileNumber::Int64,DataSetFile::String; DimsVolCross=(100,100),DepthVol=nothing,DimsSurfCross=(100,),WidthPointProfile=50km)\n\nThis is a convenience function (mostly for backwards compatibility with the MATLAB GUI) that loads the data from file & projects it onto a profile\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ExtractSubvolume-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::CartData; Interpolate=false, X_level=nothing, Y_level=nothing, Z_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n2D Example along a cross-section through 3D data:\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,-300:25:0);\njulia> Data = Z.*2\njulia> Data_Int = Int64.(Data)\njulia> DataSet_Cart = CartData(X,Y,Z,(Data=Data,Data_Int=Data_Int, Velocity=(X,Y,Z)))\n\njulia> Data_cross = CrossSection(DataSet_Cart, Start=(11.0,35), End=(19, 39.0))\nCartData\n size : (100, 100, 1)\n x ϵ [ 11.0 : 19.0]\n y ϵ [ 35.0 : 39.0]\n z ϵ [ -300.0 : 0.0]\n fields : (:Data, :Data_Int, :Velocity, :FlatCrossSection)\n attributes: [\"note\"]\n\njulia> Data_extracted = ExtractSubvolume(Data_cross, X_level=(1,7), Z_level=(-200,-100))\n CartData\n size : (50, 50, 1)\n x ϵ [ 11.894427190999917 : 17.260990336999413]\n y ϵ [ 35.44721359549995 : 38.130495168499706]\n z ϵ [ -200.0 : -100.0]\n fields : (:FlatCrossSection, :Data, :Data_Int, :Velocity)\n attributes: [\"note\"]\njulia> typeof(Data_extracted.fields.Data_Int)\n Array{Int64, 3}\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ExtractSubvolume-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.\nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData\n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData\n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.FlattenCrossSection-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.FlattenCrossSection","text":"FlattenCrossSection(V::CartData)\n\nTakes a diagonal 3D CrossSection and flattens it to be converted to a 2D Grid by CreateCartGrid\n\nExample\n\nGrid = CreateCartGrid(size=(100,100,100), x=(0.0km, 99.9km), y=(-10.0km, 20.0km), z=(-40km,4km));\nX,Y,Z = XYZGrid(Grid.coord1D...);\nDataSet = CartData(X,Y,Z,(Depthdata=Z,));\n\nData_Cross = CrossSection(DataSet, dims=(100,100), Interpolate=true, Start=(ustrip(Grid.min[1]),ustrip(Grid.max[2])), End=(ustrip(Grid.max[1]), ustrip(Grid.min[2])))\n\nx_new = FlattenCrossSection(Data_Cross)\n\nThis flattened CrossSection can be added to original Data_Cross by AddField()\n\nData_Cross = AddField(Data_Cross,\"FlatCrossSection\", x_new)\nCartData\n size : (100, 100, 1)\n x ϵ [ 0.0 : 99.9]\n y ϵ [ -10.0 : 20.0]\n z ϵ [ -40.0 : 4.0]\n fields : (:Depthdata, :FlatCrossSection)\n attributes: [\"note\"]\n\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.FlattenCrossSection-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.FlattenCrossSection","text":"FlattenCrossSection(V::GeoData)\nThis function takes a 3D cross section through a GeoData structure and computes the distance along the cross section for later 2D processing/plotting\n```julia-repl\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)));\njulia> Data_cross = CrossSection(Data_set3D, Start=(10,30),End=(20,40))\njulia> x_profile = FlattenCrossSection(Data_cross)\njulia> Data_cross = AddField(Data_cross,\"x_profile\",x_profile)\n\n```\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GetLonLatDepthMag_QuakeML-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.GetLonLatDepthMag_QuakeML","text":"Data = GetLonLatDepthMag_QuakeML(filename::String)\n\nExtracts longitude, latitude, depth and magnitude from a QuakeML file that has been e.g. downloaded from ISC. The data is then returned in GeoData format.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.GetProcessorPartitioning-Tuple{Any}","page":"List of functions","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename; is64bit=false)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields-Tuple{AbstractGeneralGrid, Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"Data_interp = InterpolateDataFields(V::AbstractGeneralGrid, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set1= CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData\n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\njulia> X,Y,Z = XYZGrid(0:4:10, -1:.1:1, -5:.1:1 );\njulia> Data_set2= InterpolateDataFields(Data_set1, X,Y,Z)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields-Tuple{UTMData, Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D-Tuple{CartData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D","text":"InterpolateDataFields2D(V::CartData, X, Y)\n\nInterpolates a data field V on a 2D CartData grid defined by X,Y. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D","text":"InterpolateDataFields2D(Original::CartData, New::CartData; Rotate=0.0, Translate=(0,0,0), Scale=(1.0,1.0,1.0))\n\nInterpolates a data field Original on a 2D CartData grid New. Typically used for horizontal surfaces.\n\nNote: Original should have orthogonal coordinates. If it has not, e.g., because it was rotated, you'll have to specify the angle Rotate that it was rotated by\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D-Tuple{GeoData, AbstractRange, AbstractRange}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D","text":"Surf_interp = InterpolateDataFields2D(V::GeoData, x::AbstractRange, y::AbstractRange; Lat::Number, Lon::Number)\n\nInterpolates a 3D data set V with a projection point proj=(Lat, Lon) on a plane defined by x and y, where x and y are uniformly spaced. Returns the 2D array Surf_interp. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D-Tuple{GeoData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D","text":"InterpolateDataFields2D(V::GeoData, Lon, Lat)\n\nInterpolates a data field V on a 2D grid defined by Lon,Lat. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D-Tuple{UTMData, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D","text":"InterpolateDataFields2D(V::UTMData, EW, NS)\n\nInterpolates a data field V on a 2D grid defined by UTM. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields2D_vecs-NTuple{6, Any}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields2D_vecs","text":"InterpolateDataFields2D_vecs(x_vec, y_vec, depth, fields_new, X, Y)\n\nInterpolates a data field V on a 2D grid defined by UTM. Typically used for horizontal surfaces\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataFields_CrossSection-Tuple{CartData, Vararg{Any, 4}}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataFields_CrossSection","text":"InterpolateDataFields_CrossSection(V::CartData, X,Y,Z,Xcross)\n\nInterpolates data fields along a cross-section defined by Xcross and Z\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataOnSurface-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.InterpolateDataOnSurface-Tuple{ParaviewData, ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf.\n\nExample\n\njulia> Data\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n ParaviewData\n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.IsInsideClosedSTL","page":"List of functions","title":"GeophysicalModelGenerator.IsInsideClosedSTL","text":"inside = IsInsideClosedSTL(mesh::Mesh, Pt, eps=1e-3)\n\nDetermine whether a point Pt is inside a 3D closed triangular *.stl surface or not.\n\nThis implements the winding number method, following the python code: https://github.com/marmakoide/inside-3d-mesh\n\nThis again is described in the following paper by Alec Jacobson, Ladislav Kavan and Olga Sorkine-Hornung.\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.LithostaticPressure!-Union{Tuple{N}, Tuple{T}, Tuple{Array{T, N}, Array{T, N}, Number}} where {T, N}","page":"List of functions","title":"GeophysicalModelGenerator.LithostaticPressure!","text":"LithostaticPressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Load_Dataset_file-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.Load_Dataset_file","text":"Datasets = Load_Dataset_file(file_datasets::String)\n\nThis loads a CSV textfile that lists datasets, which is expected to have the following format:\n\nName,Location,Type, [Active]\nAlpArray,./Seismicity/ALPARRAY/AlpArraySeis.jld2,Point, true\nPlomerova2022,https://seafile.rlp.net/f/abccb8d3302b4ef5af17/?dl=1,Volume\n\nNote that the first line of the file is skipped.\n\nHere, the meaning of the variables is:\n\nName: The name of the dataset to be loaded\nLocation: the location of the file (directory and filename) on your local machine, or an url where we can download the file from the web. The url is expected to start with \"http\".\nType: type of the dataset (Volume, Surface, Point, Screenshot)\nActive: Do we want this file to be loaded or not? Optional parameter that defaults to true\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.LonLatDepthGrid-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Movie_Paraview-Tuple{}","page":"List of functions","title":"GeophysicalModelGenerator.Movie_Paraview","text":"pvd = Movie_Paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = Movie_Paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = Write_Paraview(Data, name, pvd=movie, time=itime)\nend\nMovie_Paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParseColumns_CSV_File-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only interested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the columns are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParseValue_CommandLineArgs-NTuple{4, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ParseValue_CommandLineArgs","text":"This parses a LaMEM command line argument string and checks if the keyword exists there\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ParseValue_LaMEM_InputFile-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ParseValue_LaMEM_InputFile","text":"value = ParseValue_LaMEM_InputFile(file,keyword,type; args::String=nothing)\n\nExtracts a certain keyword from a LaMEM input file and convert it to a certain type. Optionally, you can also pass command-line arguments which will override the value read from the input file.\n\nExample 1:\n\njulia> nmark_z = ParseValue_LaMEM_InputFile(\"SaltModels.dat\",\"nmark_z\",Int64)\n\nExample 2:\n\njulia> nmark_z = ParseValue_LaMEM_InputFile(\"SaltModels.dat\",\"nmark_z\",Int64, args=\"-nel_x 128 -coord_x -4,4\")\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PetscBinaryWrite_Vec-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.PetscBinaryWrite_Vec","text":"PetscBinaryWrite_Vec(filename, A)\n\nWrites a vector A to disk, such that it can be read with PetscBinaryRead (which assumes a Big Endian type)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PointData2NearestGrid-NTuple{6, Any}","page":"List of functions","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"count = PointData2NearestGrid(pt_x,pt_y,pt_z, X,Y,Z; radius_factor=1)\n\nThis uses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D grid point specified by X,Y,Z 3D coordinate arrays, with regular spacing (Δx,Δy,Δz). The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PointData2NearestGrid-Tuple{Any, Any, Any, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"Grid_counts = PointData2NearestGrid(pt_x,pt_y,pt_z, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D CartGrid specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PointData2NearestGrid-Tuple{Any, Any, Any, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"Grid_counts = PointData2NearestGrid(pt_x,pt_y,pt_z, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by pt_x,pt_y,pt_z coordinate vectors) are in the vicinity of 3D GeoData specified by Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PointData2NearestGrid-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"Grid_counts = PointData2NearestGrid(Point::CartData, Grid::CartData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.PointData2NearestGrid-Tuple{GeoData, GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.PointData2NearestGrid","text":"Grid_counts = PointData2NearestGrid(Point::GeoData, Grid::GeoData; radius_factor=1)\n\nUses nearest neighbour interpolation to count how many points (given by Point) are in the vicinity of a 3D Grid. The search radius is R=radius_factor*(Δx² + Δy² + Δz²)^(1/3)\n\nPoint should have 1D coordinate vectors\n\nGrid_counts is Grid but with an additional field Count that has the number of hits\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectCartData-Tuple{CartData, CartData}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectCartData-Tuple{CartData, GeoData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ProjectCartData-Tuple{CartData, UTMData, ProjectionPoint}","page":"List of functions","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ReadData_PVTR-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::ParaviewData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ReadData_VTR-Tuple{Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.ReadData_VTR","text":"coord, Data_3D_Arrays, Name_Vec = ReadData_VTR(fname)\n\nReads a VTR (structured grid) VTK file fname and extracts the coordinates, data arrays and names of the data. In general, this only contains a piece of the data, and one should open a *.pvtr file to retrieve the full data\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ReadLaMEM_InputFile-Tuple{Any}","page":"List of functions","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file, args::Union{String,Nothing}=nothing)\n\nParses a LaMEM input file and stores grid information in the Grid structure. Optionally, you can pass LaMEM command-line arguments as well.\n\nExample 1\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\")\nLaMEM Grid:\nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\nExample 2 (with command-line arguments)\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\", args=\"-nel_x 64 -coord_x -4,4\")\nLaMEM Grid:\n nel : (64, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 96, 96)\n x ϵ [-4.0 : 4.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.ReadPickedProfiles-Tuple{String}","page":"List of functions","title":"GeophysicalModelGenerator.ReadPickedProfiles","text":"This reads the picked profiles from disk and returns a vector of ProfileData\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.RemoveField-Tuple{AbstractGeneralGrid, String}","page":"List of functions","title":"GeophysicalModelGenerator.RemoveField","text":"V = RemoveField(V::AbstractGeneralGrid,field_name::String)\n\nRemoves the field with name field_name from the GeoData or CartData dataset\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.RotateTranslateScale-Tuple{Union{CartData, ParaviewData}}","page":"List of functions","title":"GeophysicalModelGenerator.RotateTranslateScale","text":"Data_R = RotateTranslateScale(Data::Union{ParaviewData, CartData}; Rotate=0, Translate=(0,0,0), Scale=(1.0,1.0,1.0), Xc=(0.0,0.0))\n\nDoes an in-place rotation, translation and scaling of the Cartesian dataset Data.\n\nParameters\n\nNote that we apply the transformations in exactly this order:\n\nScale: scaling applied to the x,y,z coordinates of the data set\nRotate: rotation around the x/y axis (around the center of the box)\nTranslate: translation\nXc: center of rotation\n\nExample\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,-50:-10);\njulia> Data_C = ParaviewData(X,Y,Z,(Depth=Z,))\nParaviewData\n size : (11, 11, 41)\n x ϵ [ 10.0 : 20.0]\n y ϵ [ 30.0 : 40.0]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\njulia> Data_R = RotateTranslateScale(Data_C, Rotate=30);\njulia> Data_R\nParaviewData\n size : (11, 11, 41)\n x ϵ [ 8.169872981077807 : 21.83012701892219]\n y ϵ [ 28.16987298107781 : 41.83012701892219]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true, is64bit=false)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Save_LaMEMTopography-Tuple{CartData, String}","page":"List of functions","title":"GeophysicalModelGenerator.Save_LaMEMTopography","text":"Save_LaMEMTopography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Screenshot_To_CartData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Screenshot_To_GeoData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true, fieldname::Symbol=:colors)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative inside the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Screenshot_To_UTMData-Tuple{String, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.Screenshot_To_UTMData","text":"Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true, fieldname=:colors)\n\nDoes the same as Screenshot_To_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.SubtractHorizontalMean-Union{Tuple{AbstractArray{T, 3}}, Tuple{T}} where T","page":"List of functions","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.SubtractHorizontalMean-Union{Tuple{AbstractMatrix{T}}, Tuple{T}} where T","page":"List of functions","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.SubtractSurfaces!-Tuple{Union{CartData, ParaviewData}, Union{CartData, ParaviewData}}","page":"List of functions","title":"GeophysicalModelGenerator.SubtractSurfaces!","text":"SubtractSurfaces!(Surface1::Union{CartData,ParaviewData}, Surface2::Union{CartData,ParaviewData})\n\nSubtracts Surface2 to Surface1. The addition happens on the Surface1.z; the fields remain unchanged\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.SubtractSurfaces!-Tuple{Union{GeoData, UTMData}, Union{GeoData, UTMData}}","page":"List of functions","title":"GeophysicalModelGenerator.SubtractSurfaces!","text":"SubtractSurfaces!(Surface1::Union{GeoData,UTMData}, Surface2::Union{GeoData,UTMData})\n\nSubtracts Surface2 to Surface1. The addition happens on the Surface1.depth; the fields remain unchanged\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Velocity_SphericalToCartesian!-Tuple{GeoData, Tuple}","page":"List of functions","title":"GeophysicalModelGenerator.Velocity_SphericalToCartesian!","text":"Velocity_SphericalToCartesian!(Data::GeoData, Velocity::Tuple)\n\nIn-place conversion of velocities in spherical velocities [Veast, Vnorth, Vup] to cartesian coordinates (for use in paraview).\n\nNOTE: the magnitude of the vector will be the same, but the individual [Veast, Vnorth, Vup] components will not be retained correctly (as a different [x,y,z] coordinate system is used in paraview). Therefore, if you want to display or color that correctly in Paraview, you need to store these magnitudes as separate fields\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Visualise","page":"List of functions","title":"GeophysicalModelGenerator.Visualise","text":"Interactive widget that allows you to explore a 3D data set DataSet in an interactive manner. It requires you to load GLMakie\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.VoteMap-Tuple{Vector{GeoData}, Vector{String}}","page":"List of functions","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values.\n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData\n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData\n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData\n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Write_Paraview","page":"List of functions","title":"GeophysicalModelGenerator.Write_Paraview","text":"pvd = Write_Paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Write_Paraview-Tuple{CartData, Any}","page":"List of functions","title":"GeophysicalModelGenerator.Write_Paraview","text":"Write_Paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.Write_Paraview-Tuple{UTMData, Any}","page":"List of functions","title":"GeophysicalModelGenerator.Write_Paraview","text":"Write_Paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.XYZGrid-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.combine_VolData-Tuple{NamedTuple}","page":"List of functions","title":"GeophysicalModelGenerator.combine_VolData","text":"VolData_combined = combine_VolData(VolData::NamedTuple; lat=nothing, lon=nothing, depth=nothing, dims=(100,100,100), dataset_preferred = 1)\n\nThis takes different volumetric datasets (specified in VolData) & merges them into a single one. You need to either provide the \"reference\" dataset within the NamedTuple (dataset_preferred), or the lat/lon/depth and dimensions of the new dataset.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{CartData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::CartData)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{CartGrid}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::CartGrid)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{GeoData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"LON,LAT,Z = coordinate_grids(Data::GeoData)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{LaMEM_grid}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::LaMEM_grid)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{ParaviewData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"X,Y,Z = coordinate_grids(Data::ParaviewData)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.coordinate_grids-Tuple{UTMData}","page":"List of functions","title":"GeophysicalModelGenerator.coordinate_grids","text":"EW,NS,Z = coordinate_grids(Data::UTMData)\n\nReturns 3D coordinate arrays\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.download_data","page":"List of functions","title":"GeophysicalModelGenerator.download_data","text":"download_data(url::String, local_filename=\"temp.dat\"; dir=pwd() )\n\nDownloads a remote dataset with name url from a remote location and saves it to the current directory\n\nExample\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\";\njulia> download_data(url)\n\"/Users/kausb/.julia/dev/GeophysicalModelGenerator/temp.dat\"\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.flip","page":"List of functions","title":"GeophysicalModelGenerator.flip","text":"Data = flip(Data::GeoData, dimension=3)\n\nThis flips the data in the structure in a certain dimension (default is z [3])\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"load_GMG(filename::String, dir=pwd())\n\nLoads a GeoData/CartData/UTMData data set from jld2 file filename Note: the filename can also be a remote url, in which case we first download that file to a temporary directory before opening it\n\nExample 1 - Load local file\n\njulia> data = load_GMG(\"test\")\nGeoData \n size : (4, 3, 3)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 19.0]\n depth ϵ [ -20.0 : -10.0]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\nExample 2 - remote download\n\njulia> url = \"https://seafile.rlp.net/f/10f867e410bb4d95b3fe/?dl=1\"\njulia> load_GMG(url)\nGeoData \n size : (149, 242, 1)\n lon ϵ [ -24.875 : 35.375]\n lat ϵ [ 34.375 : 71.375]\n depth ϵ [ -11.76 : -34.7]\n fields : (:MohoDepth,)\n attributes: [\"author\", \"year\"]\n\n\n\n\n\n","category":"function"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG-Tuple{GMG_Dataset}","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"data::NamedTuple = load_GMG(data::GMG_Dataset)\n\nLoads a dataset specified in GMG_Dataset data and returns it as a named tuple\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.load_GMG-Tuple{Vector{GMG_Dataset}}","page":"List of functions","title":"GeophysicalModelGenerator.load_GMG","text":"Data = load_GMG(Datasets::Vector{GMG_Dataset})\n\nThis loads all the active datasets in Datasets, and returns a NamedTuple with Volume, Surface, Point, Screenshot and Topography data\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.makeVolcTopo-Tuple{LaMEM_grid}","page":"List of functions","title":"GeophysicalModelGenerator.makeVolcTopo","text":"makeVolcTopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by ReadLaMEM_InputFile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Write_Paraview(Topo,\"VolcanoTopo\") # Save topography to paraview\nSaved file: VolcanoTopo.vts\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.meshgrid-Union{Tuple{T}, Tuple{AbstractVector{T}, AbstractVector{T}, AbstractVector{T}}} where T","page":"List of functions","title":"GeophysicalModelGenerator.meshgrid","text":"meshgrid(vx,vy,vz)\n\nComputes an (x,y,z)-grid from the vectors (vx,vy,vz). For more information, see the MATLAB documentation.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.remove_NaN_Surface!-Tuple{Any, Any, Any}","page":"List of functions","title":"GeophysicalModelGenerator.remove_NaN_Surface!","text":"remove_NaN_Surface!(Z,X,Y)\n\nRemoves NaN's from a grid Z by taking the closest points as specified by X and Y.\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.save_GMG-Tuple{String, Union{CartData, GeoData, UTMData}}","page":"List of functions","title":"GeophysicalModelGenerator.save_GMG","text":"save_GMG(filename::String, data::Union{GeoData, CartDat, UTMData}; dir=pwd())\n\nSaves the dataset data to a JLD2 file (name without extension) in the directory dir\n\nExample\n\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(1.0:3:10.0, 11.0:4:20.0, (-20:5:-10)*km);\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Depth3D,)) \njulia> save_GMG(\"test\",Data_set)\n\n\n\n\n\n","category":"method"},{"location":"man/listfunctions/#GeophysicalModelGenerator.voxGrav-NTuple{4, Array{Float64, 3}}","page":"List of functions","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients\n\nRequired arguments:\nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)\nRHO: 3D matrix with the density at each grid point [kg/m^3]\n\nOptional arguments:\nrefMod: 1D vector with the reference density for each depth\n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used.\n In that case, one of the corners of `RHO` is used as reference model.\n In case of \"AVG\" the reference model is the average of each depth slice.\nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\"\nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]\nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output)\noutName: name of the paraview output (do not include file type)\nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"method"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"10 - Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"10 - Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"10 - Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#1.-Download-and-import-GPS-data:","page":"10 - Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#2.-Check-and-reshape-vertical-velocity","page":"10 - Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#3.-Load-horizontal-velocities","page":"10 - Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#4.-Interpolate-topography-on-grid","page":"10 - Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#5.-Saving-and-plotting-in-Paraview","page":"10 - Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"10 - Plot GPS vectors","title":"10 - Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients\n\nRequired arguments:\nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the third)\nRHO: 3D matrix with the density at each grid point [kg/m^3]\n\nOptional arguments:\nrefMod: 1D vector with the reference density for each depth\n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used.\n In that case, one of the corners of `RHO` is used as reference model.\n In case of \"AVG\" the reference model is the average of each depth slice.\nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\"\nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]\nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output)\noutName: name of the paraview output (do not include file type)\nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#1.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#2.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#3.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#4.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#5.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/visualise/#Visualisation","page":"Visualisation","title":"Visualisation","text":"","category":"section"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> using GeophysicalModelGenerator, GLMakie\njulia> using GMT, JLD2","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> ;\nshell> cd ~/Downloads/Zhao_etal_2016_data/ ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Now you can use the backspace key to return to the REPL, where we will load the data","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Data = JLD2.load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\"); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"At this stage you can look at it with","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Note that this tends to take a while, the first time you do this (faster afterwards).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Let's add topography to the plot as well, which requires us to first load that:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Topo = ImportTopo([0,18,38,52], file=\"@earth_relief_01m.grd\");\njulia> Visualise(Data, Topography=Topo); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Which will look like: (Image: Tutorial_Visualize)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> p=ProjectionPoint(Lon=10, Lat=45)\nProjectionPoint(45.0, 10.0, 578815.302916711, 4.983436768349297e6, 32, true)\njulia> Data_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,-1000:10:-1));\njulia> Topo_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,0));\njulia> Topo_Cart = ProjectCartData(Topo_Cart, Topo, p)\nCartData \n size : (121, 121, 1)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -3.6270262031545473 : 3.654942280296281]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Data_Cart = ProjectCartData(Data_Cart, Data, p)\nCartData \n size : (121, 121, 100)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -1000.0 : -10.0]\n fields : (:dVp_Percentage,)\n attributes: [\"note\"]","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"And once we have done that, you can visualize the data in the same way:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data_Cart, Topography=Topo_Cart)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Visualise","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#2-3D-tomography-model-that-is-given-as-a-netCDF-file","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"2 - 3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"2 - 3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#1.-Download-data","page":"2 - 3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#2.-Read-data-into-Julia","page":"2 - 3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> filename = (\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length\n--------------------------------------------------------------------------------------------------------------------------\ndepth 301\nlatitude 100\nlongitude 100\n\n##### Variables #####\n\nName Type Dimensions\n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth\nlatitude FLOAT latitude\nlongitude FLOAT longitude\nVs FLOAT longitude latitude depth\n\n##### Attributes #####\n\nVariable Name Value\n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de\nglobal data_revision r.0.0\nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1\nglobal id MeRE2020\nglobal author_name Amr EL-Sharkawy\nglobal comment model converted to netCDF by IRIS EMC\nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC\nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc\nglobal author_url https://www.seismologie.ifg.uni-kiel.de\nglobal reference El-Sharkawy, et al. (2020)\nglobal repository_name EMC\nglobal Conventions CF-1.0\nglobal Metadata_Conventions Unidata Dataset Discovery v1.0\nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km\ndepth long_name depth in km\ndepth display_name depth in km\ndepth positive down\nlatitude units degrees_north\nlatitude long_name Latitude; positive north\nlatitude standard_name latitude\nlongitude units degrees_east\nlongitude long_name Longitude; positive east\nlongitude standard_name longitude\nVs units km.s-1\nVs long_name Shear wave velocity\nVs display_name S Velocity (km/s)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions\n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth\nlatitude FLOAT latitude\nlongitude FLOAT longitude\nVs FLOAT longitude latitude depth","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regular grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the command ncread:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#3.-Reformat-the-coordinate-data","page":"2 - 3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\nLon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#4.-Generate-Paraview-file","page":"2 - 3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> Data_set = GeoData(Lon3D,Lat3D,Depth3D,(Vs_km_s=Vs_3D,))\nGeoData\n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,)\njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#5.-Plotting-data-in-Paraview","page":"2 - 3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#6.-Julia-script","page":"2 - 3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"2 - 3D seismic tomography from netCDF","title":"2 - 3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview\nGeophysicalModelGenerator.Movie_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"pvd = Write_Paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\nWrite_Paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\nWrite_Paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"function"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Movie_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Movie_Paraview","text":"pvd = Movie_Paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = Movie_Paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = Write_Paraview(Data, name, pvd=movie, time=itime)\nend\nMovie_Paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"function"},{"location":"man/license/","page":"License","title":"License","text":"EditURL = \"https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/LICENSE.md\"","category":"page"},{"location":"man/license/#license","page":"License","title":"License","text":"","category":"section"},{"location":"man/license/","page":"License","title":"License","text":"MIT LicenseCopyright (c) 2021 Boris Kaus, Marcel Thielmann and Authors (see Authors)Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"EditURL = \"../../../tutorials/Tutorial_Votemaps.jl\"","category":"page"},{"location":"man/Tutorial_Votemaps/#12-Votemaps","page":"12 - VoteMaps","title":"12 - Votemaps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#Aim","page":"12 - VoteMaps","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.","category":"page"},{"location":"man/Tutorial_Votemaps/#Steps","page":"12 - VoteMaps","title":"Steps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#1.-Load-data","page":"12 - VoteMaps","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to https://seafile.rlp.net/d/22b0fb85550240758552/","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"using JLD2, GeophysicalModelGenerator\n\nPwave_Zhao = load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\")\nPSwave_Koulakov = load(\"Koulakov_Europe.jld2\",\"DataKoulakov_Alps\")\nPwave_Paffrath = load(\"Paffrath_Pwave.jld2\",\"Data_set_Paffrath2021_Vp\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Pwave_Paffrath\nGeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 km : 31.0385 km]\n fields: (:dVp_Percentage, :Vp, :Resolution)\n\nPSwave_Koulakov\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)","category":"page"},{"location":"man/Tutorial_Votemaps/#2.-Creating-a-Votemap","page":"12 - VoteMaps","title":"2. Creating a Votemap","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"The idea of Votemaps is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)\nEverything that fulfills this criteria gets the number 1, everything else 0.\nDo the same with other tomographic models (using the same criteria or a different one).\nMake sure that all tomographic models are interpolated to the same grid.\nSum up the 3 models.\nThe resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"So how do we create Votemaps? Doing this is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"], dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"GeoData\n size : (100, 100, 100)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -606.0385 km : -10.0 km]\n fields: (:VoteMap,)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Write_Paraview(Data_VoteMap, \"VoteMap_Alps\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"In paraview, this gives (Image: Tutorial_VoteMap)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_Percentage>3.0\", \"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"],\n dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"12 - VoteMaps","title":"12 - VoteMaps","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/projection/#Projecting-and-converting-data","page":"Projection","title":"Projecting & converting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid). ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.","category":"page"},{"location":"man/projection/#1.-Converting","page":"Projection","title":"1. Converting","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Converting from one coordinate system to the other is straightforward. Let's use Europe as an example:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo(lon = [-10, 45], lat=[25, 50], file=\"@earth_relief_20m\")\nGeoData \n size : (165, 75, 1)\n lon ϵ [ -10.0 : 44.666666666666664]\n lat ϵ [ 25.0 : 49.666666666666664]\n depth ϵ [ -4.9855 km : 3.123 km]\n fields: (:Topography,)\njulia> Write_Paraview(Topo,\"Topo\")\nSaved file: Topo.vts","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"The result is shown on the globe as: (Image: Topo_Europe_GeoData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can convert this to UTM zone as:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert(UTMData, Topo)\nUTMData \n UTM zone : 29-38 North\n size : (165, 75, 1)\n EW ϵ [ 197181.31221507967 : 769155.4572884373]\n NS ϵ [ 2.7649477474783654e6 : 5.505892073781423e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> p=ProjectionPoint(Lon=17.3, Lat=37.5)\nProjectionPoint(37.5, 17.3, 703311.4380385976, 4.152826288024972e6, 33, true)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Projecting the GeoData set using this projection point is done with:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Convert2UTMzone(Topo,p)\nUTMData \n UTM zone : 33-33 North\n size : (165, 75, 1)\n EW ϵ [ -2.0750691599137965e6 : 3.581351293385453e6]\n NS ϵ [ 2.7649477474783654e6 : 5.938114212160672e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is now in UTM Data (in meters), it is distorted. (Image: Topo_Europe_UTMData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Often it is more convenient to have this in CartData, which is done in a similar manner:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart = Convert2CartData(Topo,p)\nCartData \n size : (165, 75, 1)\n x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]\n y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]\n z ϵ [ -4.9855 km : 3.123 km]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"This shows that the model is ~5600 by 3000 km. (Image: Topo_Europe_CartData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal. ","category":"page"},{"location":"man/projection/#2.-Projecting-data","page":"Projection","title":"2. Projecting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"For use with LaMEM, you would need an orthogonal cartesian grid. From the last command above we get some idea on the area, so we can create this:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = CartData(XYZGrid(-2000:20:2000,-1000:20:1000,0))\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Next, we can project the topographic data (in GeoData format) on this orthogonal grid","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = ProjectCartData(Topo_Cart_orth, Topo, p)\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ -4.485650671162607 km : 2.5909655318121865 km]\n fields : (:Topography,)\njulia> Write_Paraview(Topo_Cart_orth,\"Topo_Cart_orth\"); ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"(Image: Topo_Europe_CartData_Proj) So this interpolates the topographic data from the GeoData to the orthogonal cartesian grid (which can be used with LaMEM, for example).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can do similar projections with full 3D data sets or pointwise data. ","category":"page"},{"location":"man/projection/#3.-List-of-functions","page":"Projection","title":"3. List of functions","text":"","category":"section"},{"location":"man/projection/#@docs","page":"Projection","title":"```@docs","text":"","category":"section"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2CartData","page":"Projection","title":"GeophysicalModelGenerator.Convert2CartData","text":"","category":"section"},{"location":"man/projection/#GeophysicalModelGenerator.ProjectCartData","page":"Projection","title":"GeophysicalModelGenerator.ProjectCartData","text":"","category":"section"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2UTMzone","page":"Projection","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"","category":"section"},{"location":"man/projection/#","page":"Projection","title":"```","text":"","category":"section"},{"location":"man/tutorial_UTM/#11-Read-in-UTM-data","page":"11 - Read UTM data","title":"11 - Read in UTM data","text":"","category":"section"},{"location":"man/tutorial_UTM/#Goal","page":"11 - Read UTM data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004","category":"page"},{"location":"man/tutorial_UTM/#Steps","page":"11 - Read UTM data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_UTM/#1.-Download-and-import-UTM-data:","page":"11 - Read UTM data","title":"1. Download and import UTM data:","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)\t\t\t\t\t\n# when using the data please cite as: \t\t\t\t\t\n# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004\nX COORD (UTM Zone 32N)\tY COORD (UTM Zone 32N)\tTOP (m.a.s.l)\tTHICKNESS (m)\tDENSITY (Kg/m3)\n286635\t4898615\t-24823.2533\t70418.125\t3305\n286635\t4918615\t-25443.48901\t69410.01563\t3305\n286635\t4938615\t-28025.24511\t66402.49219\t3305\n286635\t4958615\t-32278.13135\t61663.48438\t3305\n286635\t4978615\t-35885.5625\t57459.14063\t3305\n286635\t4998615\t-37270.9812\t55318.71094\t3305\n286635\t5018615\t-36134.30481\t55497.16406\t3305\n286635\t5038615\t-34866.0697\t55555.41406\t3305","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data=readdlm(\"2019-004_Spooner_Lithospheric Mantle.txt\",skipstart=4)\n1023×5 Matrix{Float64}:\n 286635.0 4.89862e6 -24823.3 70418.1 3305.0\n 286635.0 4.91862e6 -25443.5 69410.0 3305.0\n 286635.0 4.93862e6 -28025.2 66402.5 3305.0\n 286635.0 4.95862e6 -32278.1 61663.5 3305.0\n ⋮ \n 926635.0 5.45862e6 -35302.7 83215.6 3335.0\n 926635.0 5.47862e6 -34908.6 84203.0 3335.0\n 926635.0 5.49862e6 -34652.4 85398.3 3335.0","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> ew, ns, depth, thick, rho = data[:,1], data[:,2], data[:,3], data[:,4], data[:,5];","category":"page"},{"location":"man/tutorial_UTM/#2.-Check-and-reshape-vertical-velocity","page":"11 - Read UTM data","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> res = ( length(unique(ns)), length(unique(ew)), 1)\njulia> EW = reshape(ew,res) \njulia> NS = reshape(ns,res)\njulia> Depth = reshape(depth,res)\njulia> T = reshape(thick,res)\njulia> Rho = reshape(rho,res)","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"Next we can examine EW: ","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> EW\n31×33×1 Array{Float64, 3}:\n[:, :, 1] =\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n ⋮ ⋮ ⋱ ⋮ \n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> EW = permutedims(EW,[2 1 3]) \njulia> NS = permutedims(NS,[2 1 3]) \njulia> Depth = permutedims(Depth,[2 1 3]) \njulia> T = permutedims(T,[2 1 3]) \njulia> Rho = permutedims(Rho,[2 1 3]) ","category":"page"},{"location":"man/tutorial_UTM/#3.-Create-UTMData-structure","page":"11 - Read UTM data","title":"3. Create UTMData structure","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"Next we can add the data to the UTMData structure. In this, we use the information that the UTM zone was 32 North.","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> Data_LM = UTMData(EW,NS,Depth,32, true, (Thickness=T/1e3*km, Density=Rho*kg/m^3 ))\nUTMData \n UTM zone : 32-32 North\n size : (33, 31, 1)\n EW ϵ [ 286635.0 : 926635.0]\n NS ϵ [ 4.898615e6 : 5.498615e6]\n depth ϵ [ -52579.56788 m : -20873.400850000003 m]\n fields : (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/#4.-Saving-and-plotting-in-Paraview","page":"11 - Read UTM data","title":"4. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"We can transfer this into a GeoData structure as:","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> Data_LM_lonlat = convert(GeoData,Data_LM)\nGeoData \n size : (33, 31, 1)\n lon ϵ [ 6.046903388679526 : 14.892535147436673]\n lat ϵ [ 44.11618022783332 : 49.64004892531006]\n depth ϵ [ -52.57956788 km : -20.873400850000003 km]\n fields: (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"and save it to Paraview in the usual way","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"julia> Write_Paraview(Data_LM_lonlat, \"Data_LM_lonlat\")","category":"page"},{"location":"man/tutorial_UTM/","page":"11 - Read UTM data","title":"11 - Read UTM data","text":"Opening and plotting the vertical field gives: (Image: Tutorial_UTM)","category":"page"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nAdd lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.Save_LaMEMTopography\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.ReadData_PVTR\nGeophysicalModelGenerator.AddBox!\nGeophysicalModelGenerator.AddSphere!\nGeophysicalModelGenerator.AddEllipsoid!\nGeophysicalModelGenerator.AddCylinder!\nGeophysicalModelGenerator.makeVolcTopo\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.LithosphericTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.Compute_Phase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.CreatePartitioningFile","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file, args::Union{String,Nothing}=nothing)\n\nParses a LaMEM input file and stores grid information in the Grid structure. Optionally, you can pass LaMEM command-line arguments as well.\n\nExample 1\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\")\nLaMEM Grid:\nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\nExample 2 (with command-line arguments)\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\", args=\"-nel_x 64 -coord_x -4,4\")\nLaMEM Grid:\n nel : (64, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 96, 96)\n x ϵ [-4.0 : 4.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename; is64bit=false)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout. By default this is done for a 32bit PETSc installation, which will fail if you actually use a 64bit version.\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMTopography","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMTopography","text":"Save_LaMEMTopography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true, is64bit=false)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor. By default it is assumed that the partitioning file was generated on a 32bit PETSc installation. If Int64 was used instead, set the flag.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::ParaviewData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData\n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddBox!","page":"LaMEM","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp(),LithosphericTemp()\n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddSphere!","page":"LaMEM","title":"GeophysicalModelGenerator.AddSphere!","text":"AddSphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddSphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddEllipsoid!","page":"LaMEM","title":"GeophysicalModelGenerator.AddEllipsoid!","text":"AddEllipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, axes=Tuple{3},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddEllipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddCylinder!","page":"LaMEM","title":"GeophysicalModelGenerator.AddCylinder!","text":"AddCylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base=Tuple{3}, cap=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases()\nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp()\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddCylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview\n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\"\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.makeVolcTopo","page":"LaMEM","title":"GeophysicalModelGenerator.makeVolcTopo","text":"makeVolcTopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by ReadLaMEM_InputFile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid:\n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData\n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Write_Paraview(Topo,\"VolcanoTopo\") # Save topography to paraview\nSaved file: VolcanoTopo.vts\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantTemp","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LinearTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LinearTemp","text":"LinearTemp(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"LaMEM","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCoolingTemp(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.SpreadingRateTemp","page":"LaMEM","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericTemp","text":"LithosphericTemp(Tsurface=0.0, Tpot=1350.0, dTadi=0.5, \n ubound=\"const\", lbound=\"const, utbf = 50.0e-3, ltbf = 10.0e-3, \n age = 120.0, dtfac = 0.9, nz = 201, \n rheology = example_CLrheology() \n )\n\nCalculates a 1D temperature profile [C] for variable thermal parameters including radiogenic heat source and linearly interpolates the temperature profile onto the box. The thermal parameters are defined in rheology and the structure of the lithosphere is define by LithosphericPhases().\n\nParameters\n\nTsurface : surface temperature [C]\nTpot : potential mantle temperature [C]\ndTadi : adiabatic gradient [K/km]\nubound : Upper thermal boundary condition [\"const\",\"flux\"] \nlbound : Lower thermal boundary condition [\"const\",\"flux\"]\nutbf : Upper thermal heat flux [W/m]; if ubound == \"flux\"\nltbf : Lower thermal heat flux [W/m]; if lbound == \"flux\"\nage : age of the lithosphere [Ma]\ndtfac : Diffusion stability criterion to calculate T_age\nnz : Grid spacing for the 1D profile within the box\nrheology : Structure containing the thermal parameters for each phase [default example_CLrheology]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantPhase","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.Compute_Phase","page":"LaMEM","title":"GeophysicalModelGenerator.Compute_Phase","text":"Phase = Compute_Phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = Compute_Phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericPhases","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 15], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : The thickness of each layer, ordered from top to bottom. The thickness of the last layer does not have to be specified.\nPhases : The phases of the layers, ordered from top to bottom.\nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab are set to Phases[end].\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.CreatePartitioningFile","page":"LaMEM","title":"GeophysicalModelGenerator.CreatePartitioningFile","text":"CreatePartitioningFile(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\", verbose=true)\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#4-Extract-topographic-data-from-GMT.jl","page":"4 - Create GMT-based topography","title":"4 - Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"4 - Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"4 - Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#1.-Download-topographic-data-of-the-Alpine-region","page":"4 - Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded. ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo([4,20,37,49], file=\"@earth_relief_01m.grd\")\nGeoData \n size : (960, 720, 1)\n lon ϵ [ 4.0 : 19.983333333333334]\n lat ϵ [ 37.0 : 48.983333333333334]\n depth ϵ [ -3.8725 km : 4.2495 km]\n fields: (:Topography,)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area. ","category":"page"},{"location":"man/tutorial_GMT_Topography/#2.-Save","page":"4 - Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"Transforming this to Paraview is a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"julia> Write_Paraview(Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"4 - Create GMT-based topography","title":"4 - Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"EditURL = \"../../../tutorials/LaPalma_example.jl\"","category":"page"},{"location":"man/LaPalma_example/#14-Create-a-Cartesian-Model-Setup-for-La-Palma","page":"14 - Cartesian Volcano Model","title":"14 - Create a Cartesian Model Setup for La Palma","text":"","category":"section"},{"location":"man/LaPalma_example/#Aim","page":"14 - Cartesian Volcano Model","title":"Aim","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of the Cumbre Viejo eruption in La Palma, which is a volcanic island that erupted from mid september 2021 - december 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.","category":"page"},{"location":"man/LaPalma_example/#1.-Load-data","page":"14 - Cartesian Volcano Model","title":"1. Load data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"We will use two types of data to create the model","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Topography\nEarthquake locations","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"We start with loading the required packages, which includes GMT to download topography (an optional dependency for GeophysicalModelGenerator)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"using GeophysicalModelGenerator, GMT","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In case you managed to install GMT on your machine, you can automatically download the topography with","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file=\"@earth_relief_03s.grd\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"pwd()","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Load the data:","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Topo=load(\"Topo_LaPalma.jld2\",\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from https://www.ign.es/web/ign/portal/vlc-catalogo). Download that here","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"data_all_EQ = load(\"EQ_Data.jld2\",\"data_all_EQ\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Write the data to paraview with","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Write_Paraview(data_all_EQ,\"data_all_EQ\",PointsData=true)\nWrite_Paraview(Topo,\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"As earthquakes are point-wise data, you have to specify this. (Image: LaPalma_EQTopo_GeoData) Note that this data is not in \"easy\" coordinates (see coordinate axis in the plot, where z is not pointing upwards).","category":"page"},{"location":"man/LaPalma_example/#2.-Convert-data","page":"14 - Cartesian Volcano Model","title":"2. Convert data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"proj = ProjectionPoint(Lon=-17.84, Lat=28.56)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Once this is done you can convert the topographic data to the cartesian reference frame","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"EQ_cart = Convert2CartData(data_all_EQ, proj);\nTopo_cart = Convert2CartData(Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In a next step, the routine ProjectCartData projects a GeoData structure to a CartData struct","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Let's have a look at the data:","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Write_Paraview(EQ_cart,\"EQ_cart\",PointsData=true)\nWrite_Paraview(Topo_LaMEM,\"Topo_LaMEM\")\n\n\n#=","category":"page"},{"location":"man/LaPalma_example/#3.-Create-LaMEM-setup","page":"14 - Cartesian Volcano Model","title":"3. Create LaMEM setup","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Grid = ReadLaMEM_InputFile(\"LaPalma.dat\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celsius).","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Phases = ones(Int32,size(Grid.X))*2;\nTemp = ones(Float64,size(Grid.X));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Geotherm = 30;\nTemp = -Grid.Z.*Geotherm;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Temp[Temp.<20] .= 20;\nTemp[Temp.>1350] .= 1350;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to \"mantle\":","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"ind = findall( Grid.Z .< -40);\nPhases[ind] .= 3;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Everything above the free surface is assumed to be \"air\"","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"ind = AboveSurface(Grid, Topo_cart);\nPhases[ind] .= 0;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"And all \"air\" points that are below sea-level becomes \"water\"","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"ind = findall( (Phases.==0) .& (Grid.Z .< 0));\nPhases[ind] .= 1;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Looking at the seismicity, there is a swarm at around 35 km depth","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"A shallower one exists as well","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"And there might be a mid-crustal one","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"We can generate a 3D model setup, which must include the Phases and Temp arrays","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\nWrite_Paraview(Model3D,\"Model3D\")","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"The model setup looks like this (Image: LaMEM_ModelSetup_LaPalma)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"We can create a LaMEM marker file from the Model3D setup and the (cartesian) topography","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Save_LaMEMTopography(Topo_cart, \"Topography.txt\")\nSave_LaMEMMarkersParallel(Model3D)","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"=#","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"","category":"page"},{"location":"man/LaPalma_example/","page":"14 - Cartesian Volcano Model","title":"14 - Cartesian Volcano Model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.\nCreate movies for representation of earthquake or wave propagation.\nCreate geodynamic input models (for LaMEM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#10-Plot-ISC-earthquake-data","page":"9 - ISC earthquake data","title":"10 - Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"9 - ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"9 - ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#1.-Download-data","page":"9 - ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#2.-Read-data-into-Julia","page":"9 - ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is separated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric formats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"9 - ISC earthquake data","title":"9 - ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#5-Add-coastlines","page":"5 - Coastlines","title":"5 - Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"5 - Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"5 - Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#1.-Coast-lines","page":"5 - Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#1.1-Download-land/sea-data","page":"5 - Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#1.2-Save-in-Paraview","page":"5 - Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"5 - Coastlines","title":"5 - Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/previews/PR67/siteinfo.js b/previews/PR67/siteinfo.js
new file mode 100644
index 00000000..66e3f145
--- /dev/null
+++ b/previews/PR67/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "previews/PR67";
diff --git a/stable b/stable
new file mode 120000
index 00000000..d5d76e73
--- /dev/null
+++ b/stable
@@ -0,0 +1 @@
+v0.4.8
\ No newline at end of file
diff --git a/v0.2 b/v0.2
new file mode 120000
index 00000000..81fd7ba0
--- /dev/null
+++ b/v0.2
@@ -0,0 +1 @@
+v0.2.0
\ No newline at end of file
diff --git a/v0.2.0/assets/documenter.js b/v0.2.0/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.2.0/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.2.0/assets/img/Fig13_mapview.png b/v0.2.0/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.2.0/assets/img/Fig13_mapview.png differ
diff --git a/v0.2.0/assets/img/Lippitsch_Fig13a.png b/v0.2.0/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.2.0/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Coastlines.png b/v0.2.0/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GMT_topography.png b/v0.2.0/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GPS_1.png b/v0.2.0/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GPS_2.png b/v0.2.0/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GPS_3.png b/v0.2.0/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.2.0/assets/img/Tutorial_GPS_4.png b/v0.2.0/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ISC.png b/v0.2.0/assets/img/Tutorial_ISC.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ISC.png differ
diff --git a/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.2.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.2.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.2.0/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.2.0/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.2.0/assets/search.js b/v0.2.0/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.2.0/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers compare them with other data sets in 3D using paraview.
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
Take a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Cartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);
+Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);
+numel_topo = prod(size(Lon));
+Depth[:,:,1] = 1e-3*G.z';
+DataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
diff --git a/v0.2.0/man/tutorial_ISC_data/index.html b/v0.2.0/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..7600518f
--- /dev/null
+++ b/v0.2.0/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.hl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
diff --git a/v0.2.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.2.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..5af28e9d
--- /dev/null
+++ b/v0.2.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
This document was generated with Documenter.jl on Tuesday 29 June 2021. Using Julia version 1.6.1.
diff --git a/v0.2.0/search_index.js b/v0.2.0/search_index.js
new file mode 100644
index 00000000..4c7c97b8
--- /dev/null
+++ b/v0.2.0/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nTake a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(Volume::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \nGeoData \n size : (6, 3, 13)\n lon ϵ [ 10.0 : 15.0]\n lat ϵ [ 30.0 : 32.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::GeoData, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface.\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\n#Example First we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"7. Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.hl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Julia-script","page":"3D seismic tomography from ASCII","title":"8. Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \n\nExample\n\njulia> Lat = 1.0:10.0;\njulia> Lon = 11.0:20.0;\njulia> Depth = (-20:-11)*km;\njulia> Data = zeros(size(Lon));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon,Lat,Depth,(DataFieldName=Data,)) \nGeoData \n size : (10,)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 20.0]\n depth ϵ [ -20 km : -11 km]\n fields: (:DataFieldName,)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(CartData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 3.5, 46.0, -400.0)\njulia> Corner_UpperRight = (16.0, 42.5, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = [3.5 ; 46.0 ; -400.0 ]\n └ lower right = [16.0 ; 42.5 ; -400.0 ]\n └ upper left = [3.5 ; 46.0 ; 0.0 ]\n └ upper right = [16.0 ; 42.5 ; 0.0 ]\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 3.4999999999999996 : 16.0]\n lat ϵ [ 42.49999999999999 : 46.00000000000001]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"4. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"5. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plots GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plots GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plots GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plots GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plots GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plots GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plots GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plots GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plots GPS vectors","title":"Plots GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"Write_Paraview(DataSet::CartData, filename=\"test\"; PointsData=false)\n\nWrites a structure with Geodata to a paraview (or VTK) file\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\")\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you, from a certain region:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GMT\njulia> G = gmtread(\"@earth_relief_01m.grd\", limits=[4,20,37,49]);","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end-1],G.y[1:end-1],0);\njulia> Depth[:,:,1] = 1e-3*G.z';\njulia> data_Topo = GeoData(Lon, Lat, Depth, (Topography=Depth*km,))\njulia> Write_Paraview(data_Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers compare them with other data sets in 3D using paraview. ","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.2.0/siteinfo.js b/v0.2.0/siteinfo.js
new file mode 100644
index 00000000..057c824f
--- /dev/null
+++ b/v0.2.0/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.2.0";
diff --git a/v0.3 b/v0.3
new file mode 120000
index 00000000..3e13853a
--- /dev/null
+++ b/v0.3
@@ -0,0 +1 @@
+v0.3.2
\ No newline at end of file
diff --git a/v0.3.0/assets/documenter.js b/v0.3.0/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.3.0/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.3.0/assets/img/Digitizer_1.png b/v0.3.0/assets/img/Digitizer_1.png
new file mode 100644
index 00000000..5f731462
Binary files /dev/null and b/v0.3.0/assets/img/Digitizer_1.png differ
diff --git a/v0.3.0/assets/img/Digitizer_2.png b/v0.3.0/assets/img/Digitizer_2.png
new file mode 100644
index 00000000..59837df0
Binary files /dev/null and b/v0.3.0/assets/img/Digitizer_2.png differ
diff --git a/v0.3.0/assets/img/Digitizer_3.png b/v0.3.0/assets/img/Digitizer_3.png
new file mode 100644
index 00000000..24725997
Binary files /dev/null and b/v0.3.0/assets/img/Digitizer_3.png differ
diff --git a/v0.3.0/assets/img/Fig13_mapview.png b/v0.3.0/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.3.0/assets/img/Fig13_mapview.png differ
diff --git a/v0.3.0/assets/img/Lippitsch_Fig13a.png b/v0.3.0/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.3.0/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.3.0/assets/img/Readme_pic.png b/v0.3.0/assets/img/Readme_pic.png
new file mode 100644
index 00000000..61fd8a00
Binary files /dev/null and b/v0.3.0/assets/img/Readme_pic.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Coastlines.png b/v0.3.0/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GMT_topography.png b/v0.3.0/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GPS_1.png b/v0.3.0/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GPS_2.png b/v0.3.0/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GPS_3.png b/v0.3.0/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.3.0/assets/img/Tutorial_GPS_4.png b/v0.3.0/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ISC.png b/v0.3.0/assets/img/Tutorial_ISC.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ISC.png differ
diff --git a/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.3.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.3.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.3.0/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.3.0/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.3.0/assets/search.js b/v0.3.0/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.3.0/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers compare them with other data sets in 3D using paraview.
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
Take a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Cartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
You first need to install a package called GeoParams.jl, after which you install GeophysicalModelGenerator.jl. It will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is: - Find a common region between the different GeoData sets (overlapping lon/lat/depth regions) - Interpolate the fields of all DataSets to common coordinates - Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0. - Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);
+Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);
+numel_topo = prod(size(Lon));
+Depth[:,:,1] = 1e-3*G.z';
+DataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
diff --git a/v0.3.0/man/tutorial_ISC_data/index.html b/v0.3.0/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..dbc275c9
--- /dev/null
+++ b/v0.3.0/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
diff --git a/v0.3.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.3.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..6efeab00
--- /dev/null
+++ b/v0.3.0/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
This document was generated with Documenter.jl on Thursday 22 July 2021. Using Julia version 1.6.2.
diff --git a/v0.3.0/search_index.js b/v0.3.0/search_index.js
new file mode 100644
index 00000000..46465a8b
--- /dev/null
+++ b/v0.3.0/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nTake a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a Cartesian data structure\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(Volume::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData \n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::GeoData, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is: - Find a common region between the different GeoData sets (overlapping lon/lat/depth regions) - Interpolate the fields of all DataSets to common coordinates - Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0. - Sum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values. \n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData \n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\n#Example First we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::CartData, Surf::CartData)\n\nInterpolates a 3D data set V on a surface defined by Surf. nex\n\nExample\n\njulia> Data\nCartData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nCartData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n CartData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.RotateTranslateScale!","page":"Tools","title":"GeophysicalModelGenerator.RotateTranslateScale!","text":"RotateTranslateScale!(Data::CartData; Rotate=0, Translate=(0,0,0), Scale=(1.0,1.0,1.0))\n\nDoes an in-place rotation, translation and scaling of the Cartesian dataset Data. \n\nParameters\n\nNote that we apply the transformations in exactly this order:\n\nScale: scaling applied to the x,y,z coordinates of the data set\nRotate: rotation around the x/y axis (around the center of the box)\nTranslate: translation\n\nExample\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,-50:-10);\njulia> Data_C = CartData(X,Y,Z,(Depth=Z,))\nCartData \n size : (11, 11, 41)\n x ϵ [ 10.0 : 20.0]\n y ϵ [ 30.0 : 40.0]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\njulia> RotateTranslateScale!(Data_C, Rotate=30);\njulia> Data_C\nCartData \n size : (11, 11, 41)\n x ϵ [ 8.169872981077807 : 21.83012701892219]\n y ϵ [ 28.16987298107781 : 41.83012701892219]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"7. Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Julia-script","page":"3D seismic tomography from ASCII","title":"8. Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid\nGeophysicalModelGenerator.XYZGrid","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \n\nExample\n\njulia> Lat = 1.0:10.0;\njulia> Lon = 11.0:20.0;\njulia> Depth = (-20:-11)*km;\njulia> Data = zeros(size(Lon));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon,Lat,Depth,(DataFieldName=Data,)) \nGeoData \n size : (10,)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 20.0]\n depth ϵ [ -20 km : -11 km]\n fields: (:DataFieldName,)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(CartData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section & create VTS file\n3. Read data of a mapview & create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 3.5, 46.0, -400.0)\njulia> Corner_UpperRight = (16.0, 42.5, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = [3.5 ; 46.0 ; -400.0 ]\n └ lower right = [16.0 ; 42.5 ; -400.0 ]\n └ upper left = [3.5 ; 46.0 ; 0.0 ]\n └ upper right = [16.0 ; 42.5 ; 0.0 ]\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 3.4999999999999996 : 16.0]\n lat ϵ [ 42.49999999999999 : 46.00000000000001]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add https://github.com/JuliaGeodynamics/GeoParams.jl\n(@v1.6) pkg> add https://github.com/JuliaGeodynamics/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You first need to install a package called GeoParams.jl, after which you install GeophysicalModelGenerator.jl. It will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"Write_Paraview(DataSet::CartData, filename=\"test\"; PointsData=false)\n\nWrites a structure with Geodata to a paraview (or VTK) file\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#LaMEM-I/O","page":"LaMEM I/O","title":"LaMEM I/O","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM I/O","title":"LaMEM I/O","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM I/O","title":"LaMEM I/O","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.ReadData_PVTR","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM I/O","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file)\n\nParses a LaMEM input file and stores grid information in the Grid structure.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\") \nLaMEM Grid: \nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM I/O","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM I/O","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM I/O","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM I/O","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::CartData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nCartData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you, from a certain region:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GMT\njulia> G = gmtread(\"@earth_relief_01m.grd\", limits=[4,20,37,49]);","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end-1],G.y[1:end-1],0);\njulia> Depth[:,:,1] = 1e-3*G.z';\njulia> data_Topo = GeoData(Lon, Lat, Depth, (Topography=Depth*km,))\njulia> Write_Paraview(data_Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers compare them with other data sets in 3D using paraview. ","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.3.0/siteinfo.js b/v0.3.0/siteinfo.js
new file mode 100644
index 00000000..bcac4fe6
--- /dev/null
+++ b/v0.3.0/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.3.0";
diff --git a/v0.3.2/assets/documenter.js b/v0.3.2/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.3.2/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.3.2/assets/img/Digitizer_1.png b/v0.3.2/assets/img/Digitizer_1.png
new file mode 100644
index 00000000..5f731462
Binary files /dev/null and b/v0.3.2/assets/img/Digitizer_1.png differ
diff --git a/v0.3.2/assets/img/Digitizer_2.png b/v0.3.2/assets/img/Digitizer_2.png
new file mode 100644
index 00000000..59837df0
Binary files /dev/null and b/v0.3.2/assets/img/Digitizer_2.png differ
diff --git a/v0.3.2/assets/img/Digitizer_3.png b/v0.3.2/assets/img/Digitizer_3.png
new file mode 100644
index 00000000..24725997
Binary files /dev/null and b/v0.3.2/assets/img/Digitizer_3.png differ
diff --git a/v0.3.2/assets/img/Fig13_mapview.png b/v0.3.2/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.3.2/assets/img/Fig13_mapview.png differ
diff --git a/v0.3.2/assets/img/Lippitsch_Fig13a.png b/v0.3.2/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.3.2/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.3.2/assets/img/Readme_pic.png b/v0.3.2/assets/img/Readme_pic.png
new file mode 100644
index 00000000..61fd8a00
Binary files /dev/null and b/v0.3.2/assets/img/Readme_pic.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Coastlines.png b/v0.3.2/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GMT_topography.png b/v0.3.2/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GPS_1.png b/v0.3.2/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GPS_2.png b/v0.3.2/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GPS_3.png b/v0.3.2/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.3.2/assets/img/Tutorial_GPS_4.png b/v0.3.2/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ISC.png b/v0.3.2/assets/img/Tutorial_ISC.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ISC.png differ
diff --git a/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.3.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.3.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.3.2/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.3.2/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.3.2/assets/search.js b/v0.3.2/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.3.2/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers compare them with other data sets in 3D using paraview.
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
Take a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Cartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Read LaMEM processor partitioning file
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is: - Find a common region between the different GeoData sets (overlapping lon/lat/depth regions) - Interpolate the fields of all DataSets to common coordinates - Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0. - Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);
+Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);
+numel_topo = prod(size(Lon));
+Depth[:,:,1] = 1e-3*G.z';
+DataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
diff --git a/v0.3.2/man/tutorial_ISC_data/index.html b/v0.3.2/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..a055f0ab
--- /dev/null
+++ b/v0.3.2/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
diff --git a/v0.3.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.3.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..051f0f51
--- /dev/null
+++ b/v0.3.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
This document was generated with Documenter.jl on Saturday 16 October 2021. Using Julia version 1.6.3.
diff --git a/v0.3.2/search_index.js b/v0.3.2/search_index.js
new file mode 100644
index 00000000..5a25c65a
--- /dev/null
+++ b/v0.3.2/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nTake a screenshot of Georeferenced image (either a lat/lon map at a given depth or a profile) and converts it to a GeoData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth), where depth is negative in the Earth.\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a Cartesian data structure\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(Volume::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData \n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::GeoData, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is: - Find a common region between the different GeoData sets (overlapping lon/lat/depth regions) - Interpolate the fields of all DataSets to common coordinates - Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0. - Sum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values. \n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData \n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\n#Example First we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::CartData, Surf::CartData)\n\nInterpolates a 3D data set V on a surface defined by Surf. nex\n\nExample\n\njulia> Data\nCartData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nCartData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n CartData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.RotateTranslateScale!","page":"Tools","title":"GeophysicalModelGenerator.RotateTranslateScale!","text":"RotateTranslateScale!(Data::CartData; Rotate=0, Translate=(0,0,0), Scale=(1.0,1.0,1.0))\n\nDoes an in-place rotation, translation and scaling of the Cartesian dataset Data. \n\nParameters\n\nNote that we apply the transformations in exactly this order:\n\nScale: scaling applied to the x,y,z coordinates of the data set\nRotate: rotation around the x/y axis (around the center of the box)\nTranslate: translation\n\nExample\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,-50:-10);\njulia> Data_C = CartData(X,Y,Z,(Depth=Z,))\nCartData \n size : (11, 11, 41)\n x ϵ [ 10.0 : 20.0]\n y ϵ [ 30.0 : 40.0]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\njulia> RotateTranslateScale!(Data_C, Rotate=30);\njulia> Data_C\nCartData \n size : (11, 11, 41)\n x ϵ [ 8.169872981077807 : 21.83012701892219]\n y ϵ [ 28.16987298107781 : 41.83012701892219]\n z ϵ [ -50.0 : -10.0]\n fields: (:Depth,)\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max]);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"7. Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Julia-script","page":"3D seismic tomography from ASCII","title":"8. Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the latitude, longitude and depth of a data set, as well as several data sets itself.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid\nGeophysicalModelGenerator.XYZGrid","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a CartData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \n\nExample\n\njulia> Lat = 1.0:10.0;\njulia> Lon = 11.0:20.0;\njulia> Depth = (-20:-11)*km;\njulia> Data = zeros(size(Lon));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon,Lat,Depth,(DataFieldName=Data,)) \nGeoData \n size : (10,)\n lon ϵ [ 1.0 : 10.0]\n lat ϵ [ 11.0 : 20.0]\n depth ϵ [ -20 km : -11 km]\n fields: (:DataFieldName,)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(CartData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section & create VTS file\n3. Read data of a mapview & create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be at:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 3.5, 46.0, -400.0)\njulia> Corner_UpperRight = (16.0, 42.5, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = [3.5 ; 46.0 ; -400.0 ]\n └ lower right = [16.0 ; 42.5 ; -400.0 ]\n └ upper left = [3.5 ; 46.0 ; 0.0 ]\n └ upper right = [16.0 ; 42.5 ; 0.0 ]\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 3.4999999999999996 : 16.0]\n lat ϵ [ 42.49999999999999 : 46.00000000000001]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or CartData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"Write_Paraview(DataSet::CartData, filename=\"test\"; PointsData=false)\n\nWrites a structure with Geodata to a paraview (or VTK) file\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nAdd lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.AddBox!\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.ReadData_PVTR","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file)\n\nParses a LaMEM input file and stores grid information in the Grid structure.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\") \nLaMEM Grid: \nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.AddBox!","page":"LaMEM","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::LaMEM_grid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantTemp","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LinearTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LinearTemp","text":"Linear(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"LaMEM","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCooling(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.SpreadingRateTemp","page":"LaMEM","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantPhase","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericPhases","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 30], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : the thickness of the layers from top downwards\nPhases : the phases of the layers from top down. Note that this array \nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab is set to Phases[end]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::CartData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nCartData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you, from a certain region:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GMT\njulia> G = gmtread(\"@earth_relief_01m.grd\", limits=[4,20,37,49]);","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(G.x[1:end-1],G.y[1:end-1],0);\njulia> Depth[:,:,1] = 1e-3*G.z';\njulia> data_Topo = GeoData(Lon, Lat, Depth, (Topography=Depth*km,))\njulia> Write_Paraview(data_Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers compare them with other data sets in 3D using paraview. ","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.3.2/siteinfo.js b/v0.3.2/siteinfo.js
new file mode 100644
index 00000000..b2defe14
--- /dev/null
+++ b/v0.3.2/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.3.2";
diff --git a/v0.4 b/v0.4
new file mode 120000
index 00000000..d5d76e73
--- /dev/null
+++ b/v0.4
@@ -0,0 +1 @@
+v0.4.8
\ No newline at end of file
diff --git a/v0.4.2/assets/documenter.js b/v0.4.2/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.4.2/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.4.2/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png b/v0.4.2/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.4.2/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png differ
diff --git a/v0.4.2/assets/img/Digitizer_1.png b/v0.4.2/assets/img/Digitizer_1.png
new file mode 100644
index 00000000..5f731462
Binary files /dev/null and b/v0.4.2/assets/img/Digitizer_1.png differ
diff --git a/v0.4.2/assets/img/Digitizer_2.png b/v0.4.2/assets/img/Digitizer_2.png
new file mode 100644
index 00000000..59837df0
Binary files /dev/null and b/v0.4.2/assets/img/Digitizer_2.png differ
diff --git a/v0.4.2/assets/img/Digitizer_3.png b/v0.4.2/assets/img/Digitizer_3.png
new file mode 100644
index 00000000..24725997
Binary files /dev/null and b/v0.4.2/assets/img/Digitizer_3.png differ
diff --git a/v0.4.2/assets/img/Fig13_mapview.png b/v0.4.2/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.4.2/assets/img/Fig13_mapview.png differ
diff --git a/v0.4.2/assets/img/Flegrei_Geomorphology.png b/v0.4.2/assets/img/Flegrei_Geomorphology.png
new file mode 100644
index 00000000..c145ff48
Binary files /dev/null and b/v0.4.2/assets/img/Flegrei_Geomorphology.png differ
diff --git a/v0.4.2/assets/img/Flegrei_Noise.png b/v0.4.2/assets/img/Flegrei_Noise.png
new file mode 100644
index 00000000..6150ac2e
Binary files /dev/null and b/v0.4.2/assets/img/Flegrei_Noise.png differ
diff --git a/v0.4.2/assets/img/Flegrei_Seismicity.png b/v0.4.2/assets/img/Flegrei_Seismicity.png
new file mode 100644
index 00000000..30675ff4
Binary files /dev/null and b/v0.4.2/assets/img/Flegrei_Seismicity.png differ
diff --git a/v0.4.2/assets/img/Flegrei_VpVs.png b/v0.4.2/assets/img/Flegrei_VpVs.png
new file mode 100644
index 00000000..a4436fc6
Binary files /dev/null and b/v0.4.2/assets/img/Flegrei_VpVs.png differ
diff --git a/v0.4.2/assets/img/LaMEM_ModelSetup_LaPalma.png b/v0.4.2/assets/img/LaMEM_ModelSetup_LaPalma.png
new file mode 100644
index 00000000..863a18a8
Binary files /dev/null and b/v0.4.2/assets/img/LaMEM_ModelSetup_LaPalma.png differ
diff --git a/v0.4.2/assets/img/Lippitsch_Fig13a.png b/v0.4.2/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.4.2/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.4.2/assets/img/Readme_pic.png b/v0.4.2/assets/img/Readme_pic.png
new file mode 100644
index 00000000..61fd8a00
Binary files /dev/null and b/v0.4.2/assets/img/Readme_pic.png differ
diff --git a/v0.4.2/assets/img/TopoEQs_LaPalma_GeoData.png b/v0.4.2/assets/img/TopoEQs_LaPalma_GeoData.png
new file mode 100644
index 00000000..9ac618c6
Binary files /dev/null and b/v0.4.2/assets/img/TopoEQs_LaPalma_GeoData.png differ
diff --git a/v0.4.2/assets/img/Topo_Europe_CartData.png b/v0.4.2/assets/img/Topo_Europe_CartData.png
new file mode 100644
index 00000000..29f75dd0
Binary files /dev/null and b/v0.4.2/assets/img/Topo_Europe_CartData.png differ
diff --git a/v0.4.2/assets/img/Topo_Europe_CartData_Proj.png b/v0.4.2/assets/img/Topo_Europe_CartData_Proj.png
new file mode 100644
index 00000000..f79fdf09
Binary files /dev/null and b/v0.4.2/assets/img/Topo_Europe_CartData_Proj.png differ
diff --git a/v0.4.2/assets/img/Topo_Europe_GeoData.png b/v0.4.2/assets/img/Topo_Europe_GeoData.png
new file mode 100644
index 00000000..d4ef347c
Binary files /dev/null and b/v0.4.2/assets/img/Topo_Europe_GeoData.png differ
diff --git a/v0.4.2/assets/img/Topo_Europe_UTMData.png b/v0.4.2/assets/img/Topo_Europe_UTMData.png
new file mode 100644
index 00000000..3dc6756e
Binary files /dev/null and b/v0.4.2/assets/img/Topo_Europe_UTMData.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Coastlines.png b/v0.4.2/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GMT_topography.png b/v0.4.2/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GPS_1.png b/v0.4.2/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GPS_2.png b/v0.4.2/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GPS_3.png b/v0.4.2/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.4.2/assets/img/Tutorial_GPS_4.png b/v0.4.2/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.4.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.4.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.4.2/assets/img/Tutorial_SeismicityTime_1.png b/v0.4.2/assets/img/Tutorial_SeismicityTime_1.png
new file mode 100644
index 00000000..69b25f21
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_SeismicityTime_1.png differ
diff --git a/v0.4.2/assets/img/Tutorial_SeismicityTime_2.png b/v0.4.2/assets/img/Tutorial_SeismicityTime_2.png
new file mode 100644
index 00000000..09252190
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_SeismicityTime_2.png differ
diff --git a/v0.4.2/assets/img/Tutorial_SeismicityTime_3.mov b/v0.4.2/assets/img/Tutorial_SeismicityTime_3.mov
new file mode 100644
index 00000000..04ed003e
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_SeismicityTime_3.mov differ
diff --git a/v0.4.2/assets/img/Tutorial_UTM.png b/v0.4.2/assets/img/Tutorial_UTM.png
new file mode 100644
index 00000000..271b680f
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_UTM.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Visualize.png b/v0.4.2/assets/img/Tutorial_Visualize.png
new file mode 100644
index 00000000..df919f45
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Visualize.png differ
diff --git a/v0.4.2/assets/img/Tutorial_VoteMap.png b/v0.4.2/assets/img/Tutorial_VoteMap.png
new file mode 100644
index 00000000..2e318e6a
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_VoteMap.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.4.2/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.4.2/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.4.2/assets/search.js b/v0.4.2/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.4.2/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.
Create movies for representation of earthquake or wave propagation.
Create geodynamic input models (for LaMEM)
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
diff --git a/v0.4.2/man/LaPalma_example/index.html b/v0.4.2/man/LaPalma_example/index.html
new file mode 100644
index 00000000..cb1fce4c
--- /dev/null
+++ b/v0.4.2/man/LaPalma_example/index.html
@@ -0,0 +1,68 @@
+
+Generating LaMEM model · GeophysicalModelGenerator.jl
In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.
In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:
As earthquakes are point-wise data, you have to specify this. Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where z is not pointing upwards).
In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
CartData
+ size : (1921, 1441, 1)
+ x ϵ [ -86.09445705828863 km : 73.67229892155609 km]
+ y ϵ [ -63.5531883197492 km : 73.28446155584604 km]
+ z ϵ [ -4.38297802734375 km : 2.414 km]
+ fields : (:Topography,)
+
It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:
In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command
Grid = ReadLaMEM_InputFile("LaPalma.dat")
LaMEM Grid:
+ nel : (64, 64, 32)
+ marker/cell : (3, 3, 3)
+ markers : (192, 192, 192)
+ x ϵ [-50.0 : 50.0]
+ y ϵ [-40.0 : 40.0]
+ z ϵ [-80.0 : 15.0]
+
The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.
In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.
Looking at the seismicity, there is a swarm at around 35 km depth
Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.
Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory
The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
Everything that fulfills this criteria gets the number 1, everything else 0.
Do the same with other tomographic models (using the same criteria or a different one).
Make sure that all tomographic models are interpolated to the same grid.
Sum up the 3 models.
The resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
So how do we create Votemaps? Doing this is rather simple:
This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:
And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
Write_Paraview(Data_VoteMap, "VoteMap_Alps")
In paraview, this gives
You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:
Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Example
julia> Lat = 1.0:3:10.0;
+julia> Lon = 11.0:4:20.0;
+julia> Depth = (-20:5:-10)*km;
+julia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);
+julia> Lon3D
+3×4×3 Array{Float64, 3}:
+[:, :, 1] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 2] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 3] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+julia> Lat3D
+ 3×4×3 Array{Float64, 3}:
+ [:, :, 1] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 2] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 3] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+julia> Depth3D
+ 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:
+ [:, :, 1] =
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+
+ [:, :, 2] =
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+
+ [:, :, 3] =
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+julia> Data = zeros(size(Lon3D));
+julia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))
+GeoData
+ size : (3, 4, 3)
+ lon ϵ [ 11.0 : 19.0]
+ lat ϵ [ 1.0 : 10.0]
+ depth ϵ [ -20.0 km : -10.0 km]
+ fields : (:DataFieldName,)
+ attributes: ["note"]
Data structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.
depth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Cartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
Data structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers
x,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
x,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.
Example
julia> x = 0:2:10
+julia> y = -5:5
+julia> z = -10:2:2
+julia> X,Y,Z = XYZGrid(x, y, z);
+julia> Data = Z
+julia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))
+CartData
+ size : (6, 11, 7)
+ x ϵ [ 0.0 km : 10.0 km]
+ y ϵ [ -5.0 km : 5.0 km]
+ z ϵ [ -10.0 km : 2.0 km]
+ fields : (:FakeData, :Data2)
+ attributes: ["note"]
CartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Read LaMEM processor partitioning file
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.
Writes a structure with Geodatato a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), setPointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to passtimeandpvd`
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = Movie_Paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = Write_Paraview(Data, name, pvd=movie, time=itime)
+end
+Movie_Paraview(pvd=movie, Finalize=true)
Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).
If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).
Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.
As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.
Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):
Whereas this is now in UTM Data (in meters), it is distorted.
Often it is more convenient to have this in CartData, which is done in a similar manner:
julia> Topo_Cart = Convert2CartData(Topo,p)
+CartData
+ size : (165, 75, 1)
+ x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]
+ y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]
+ z ϵ [ -4.9855 km : 3.123 km]
+ fields : (:Topography,)
This shows that the model is ~5600 by 3000 km.
Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded.
The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area.
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
diff --git a/v0.4.2/man/tutorial_ISC_data/index.html b/v0.4.2/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..89e40a93
--- /dev/null
+++ b/v0.4.2/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from
Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004
Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:
# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)
+# when using the data please cite as:
+# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004
+X COORD (UTM Zone 32N) Y COORD (UTM Zone 32N) TOP (m.a.s.l) THICKNESS (m) DENSITY (Kg/m3)
+286635 4898615 -24823.2533 70418.125 3305
+286635 4918615 -25443.48901 69410.01563 3305
+286635 4938615 -28025.24511 66402.49219 3305
+286635 4958615 -32278.13135 61663.48438 3305
+286635 4978615 -35885.5625 57459.14063 3305
+286635 4998615 -37270.9812 55318.71094 3305
+286635 5018615 -36134.30481 55497.16406 3305
+286635 5038615 -34866.0697 55555.41406 3305
So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:
The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).
julia> res = ( length(unique(ns)), length(unique(ew)), 1)
+julia> EW = reshape(ew,res)
+julia> NS = reshape(ns,res)
+julia> Depth = reshape(depth,res)
+julia> T = reshape(thick,res)
+julia> Rho = reshape(rho,res)
So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
diff --git a/v0.4.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.4.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..2a160d91
--- /dev/null
+++ b/v0.4.2/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:
Two shape files containing coastline and faults:
Vilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508
Earthquake data for two volcanic unrests, in 1983-84 and 2005-2016:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
De Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817
Travel time tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Ambient noise tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Load both the the shape (.shp) files contained in "./Geomorphology/*.shp" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:
To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates
Now let's plot earthquake data provided as text files. Start loading the data contained in "./SeismicLocations/*.txt". The first column gives us a temporal marker we can use to plot earthquakes in different periods.
Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in "./TravelTmeTomography/modvPS.dat" for both cartesian and UTM coordinates.
Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files "./NoiseTomography/*.txt". We read them consecutively in a "for" loop:
julia> list_files = glob("AmbientNoiseTomography/*.txt");
+julia> li = size(list_files, 1);
+julia> for i = 1:li
+julia> nameFile = list_files[i];
+julia> name_vts = name_vts[24:26];
+julia> data = readdlm(nameFile, '\t', Float64);
+julia> WE = data[:,1];
+julia> SN = data[:,2];
+julia> depth = data[:,3];
+julia> Vs = data[:,4];
However these models are too wide, so it is better to constrain them:
julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );
+julia> WE = WE[ind];
+julia> SN = SN[ind];
+julia> depth = depth[ind];
+julia> Vs = Vs[ind];
Also, nodes are irregular, hence we create a 3D regular UTM:
This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:
Earthquake data for the 1983-84 unrest:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
You will need to download the zipped folder containing all files from here.
Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here
Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.
julia> using DelimitedFiles, GeophysicalModelGenerator, Dates
+julia> p2 = @__FILE__;
+julia> p2last = findlast("/",p2);
+julia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);
+julia> output_path = string(p3,"/");
+julia> movie = Movie_Paraview(name=string(p3,"/TemporalSeismicity"), Initialize=true);
+julia> if isdir(string(p3,"/TemporalSeismicity"))==0
+julia> mkdir(string(p3,"/TemporalSeismicity"));
+julia> end
+
Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.
julia> data = readdlm("SeismicLocations/Seismicity_UTM_1983_1984.txt", '\t', skipstart=0, header=false);
+julia> l = length(data[:,1]);
+julia> dates = Date.(zeros(l,1))
+julia> for i = 1:l
+julia> df = DateFormat("yyyymmdd");
+julia> t1 = string("19",@sprintf("%5.o", data[i,1]));
+julia> t2 = Date(t1[1:8],df);
+julia> dates[i,1] = t2;
+julia> end
+julia> WE = data[:,2];
+julia> SN = data[:,3];
+julia> depth = data[:,4];
+julia> dates_num = dates - dates[1];
+
Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.
julia> nt = 50;
+julia> dt = Dates.Day(nt);
+julia> t = minimum(dates):dt:maximum(dates);
+julia> for itime = 1:length(t)-1
+julia> name = string(p3,"/TemporalSeismicity/", string(itime));
+julia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);
+julia> we = WE[tt];
+julia> sn = SN[tt];
+julia> Depth1 = depth[tt];
+julia> DN = dates_num[tt];
+julia> label_time = Dates.value(DN[end]);
+julia> if size(tt,1)>1
+julia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));
+julia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);
+julia> end
+julia>end
+julia>Movie_Paraview(pvd=movie, Finalize=true)
+
This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.
Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.
It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:
julia> using GeophysicalModelGenerator, GLMakie
+julia> using GMT, JLD2
The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).
julia> ;
+shell> cd ~/Downloads/Zhao_etal_2016_data/
Now you can use the backspace key to return to the REPL, where we will load the data
julia> Data = JLD2.load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp");
At this stage you can look at it with
julia> Visualise(Data);
Note that this tends to take a while, the first time you do this (faster afterwards).
Let's add topography to the plot as well, which requires us to first load that:
This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.
And once we have done that, you can visualize the data in the same way:
julia> Visualise(Data_Cart, Topography=Topo_Cart)
Missing docstring.
Missing docstring for GeophysicalModelGenerator.Visualise. Check Documenter's build log for details.
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
diff --git a/v0.4.2/scripts/LaPalma.dat b/v0.4.2/scripts/LaPalma.dat
new file mode 100644
index 00000000..f64edccf
--- /dev/null
+++ b/v0.4.2/scripts/LaPalma.dat
@@ -0,0 +1,361 @@
+# Define number of elements in x, y, z-direction
+# Negative number implies corresponding number of mesh segments
+# Data is provided in the variables seg_x, seg_y, seg_z and includes:
+# * coordinates of the delimiters between the segments (n-1 points)
+# * number of cells (n points)
+# * bias coefficients (n points)
+
+
+#===============================================================================
+# Scaling
+#===============================================================================
+
+# Geometry
+units = geo
+
+# Always in SI units!!
+unit_temperature = 500
+unit_length = 1000
+unit_viscosity = 1e19
+unit_stress = 1e9
+
+#===============================================================================
+# Time stepping parameters
+#===============================================================================
+
+ dt = 5e-4 # time step
+ dt_min = 4.5e-4 # minimum time step (declare divergence if lower value is attempted)
+ dt_max = 1e-3 # maximum time step
+ inc_dt = 1 # time step increment per time step (fraction of unit)
+ CFL = 0.5 # CFL (Courant-Friedrichs-Lewy) criterion
+ CFLMAX = 0.8 # CFL criterion for elasticity
+ nstep_ini = 0 # save output for n initial steps
+ nstep_max = 20 # maximum allowed number of steps (lower bound: time_end/dt_max)
+ nstep_out = 1 # save output every n steps
+
+#===============================================================================
+# Grid & discretization parameters
+#===============================================================================
+
+# relative geometry tolerance for grid manipulations (default 1e-9)
+
+ gtol = 1e-9
+
+# Number of cells for all segments
+ nel_x = 64
+ nel_y = 64
+ nel_z = 32
+
+# Coordinates of all segments (including start and end points)
+ coord_x = -50 50
+ coord_y = -40 40
+ coord_z = -80 15
+
+#===============================================================================
+# Free surface
+#===============================================================================
+
+ surf_use = 1 # free surface activation flag
+ surf_corr_phase = 1 # air phase ratio correction flag (due to surface position)
+ surf_level = 5 # initial level
+ surf_air_phase = 0 # phase ID of sticky air layer
+ surf_max_angle = 45.0 # maximum angle with horizon (smoothed if larger)
+ surf_topo_file = LaPalma_Topo.topo # initial topography file (redundant)
+ erosion_model = 0 # erosion model [0-none (default), 1-infinitely fast]
+ sediment_model = 0 # sedimentation model [0-none (dafault), 1-prescribed rate]
+
+#===============================================================================
+# Boundary conditions
+#===============================================================================
+
+# noslip = 0 0 0 0 0 0
+
+ temp_top = 0 # Temperature @ top
+ temp_bot = 1350 # Temperature @ bottom; side BC's are flux-free
+
+ # Background strain rate parameters
+# exx_num_periods = 1 # number intervals of constant strain rate (x-axis)
+# exx_strain_rates = -5e-16 # strain rates for each interval (negative=compression)
+
+ # Free surface top boundary flag
+ open_top_bound = 1
+
+#===============================================================================
+# Jacobian & residual evaluation parameters
+#===============================================================================
+
+ gravity = 0.0 0.0 -9.81 # gravity vector
+ act_temp_diff = 1 # temperature diffusion activation flag
+ #act_steady_temp = 0 # steady-state temperature initial guess activation flag
+ #steady_temp_t = 0.1 # time for (quasi-)steady-state temperature initial guess
+ #nstep_steady = 50 # number of steps for (quasi-)steady-state temperature initial guess (default = 1)
+ act_heat_rech = 0 # heat recharge activation flag
+ init_lith_pres = 1 # initial pressure with lithostatic pressure
+ init_guess = 1 # initial guess flag
+ eta_min = 1e18 # viscosity upper bound
+ eta_max = 1e23 # viscosity lower limit
+ eta_ref = 1e19 # reference viscosity (initial guess)
+ T_ref = 20 # reference temperature
+
+#===============================================================================
+# Solver options
+#===============================================================================
+
+ SolverType = multigrid # solver [direct or multigrid]
+ MGLevels = 4 # number of MG levels [default=3]
+
+#===============================================================================
+# Model setup & advection
+#===============================================================================
+
+ msetup = files
+ mark_load_file = ./markers/mdb # marker input file (extension is .xxxxxxxx.dat)
+
+ #poly_file = ../Polygons/RoundTopShort_256_128_21_09_20.bin
+ nmark_x = 3 # markers per cell in x-direction
+ nmark_y = 3 # ... y-direction
+ nmark_z = 3 # ... z-direction
+# rand_noise = 1 # random noise flag
+ advect = rk2 # advection scheme
+ interp = minmod # velocity interpolation scheme
+# stagp_a = 0.7 # STAG_P velocity interpolation parameter
+ mark_ctrl = basic # marker control type
+ nmark_lim = 16 100 # min/max number per cell
+
+#===============================================================================
+# Output
+#===============================================================================
+
+# Grid output options (output is always active)
+ out_file_name = LaPalma_test # output file name
+ out_pvd = 1 # activate writing .pvd file
+ out_phase = 1
+ out_density = 1
+ out_visc_total = 1
+ out_visc_creep = 1
+ out_visc_plast = 1
+ out_velocity = 1
+ out_pressure = 1
+ out_over_press = 1
+ out_litho_press = 1
+ out_temperature = 1
+# out_dev_stress = 1
+ out_j2_dev_stress = 1
+# out_strain_rate = 1
+ out_j2_strain_rate = 1
+ out_plast_strain = 1
+ out_plast_dissip = 1
+ out_tot_displ = 1
+ out_moment_res = 1
+ out_cont_res = 1
+ out_yield = 1
+
+# AVD phase viewer output options (requires activation)
+ out_avd = 1 # activate AVD phase output
+ out_avd_pvd = 1 # activate writing .pvd file
+ out_avd_ref = 1 # AVD grid refinement factor
+
+# free surface output
+ out_surf = 1 # activate surface output
+ out_surf_pvd = 1 # activate writing .pvd file
+ out_surf_velocity = 1
+ out_surf_topography = 1
+ out_surf_amplitude = 1
+
+
+#===============================================================================
+# ............................ Material Parameters .............................
+#===============================================================================
+
+# ------------------- Air -------------------
+
+ Name = air
+ ID = 0
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Water -------------------
+
+ Name = water
+ ID = 1
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+# ------------------- Upper Crust -------------------
+
+ Name = Crust
+ ID = 2
+ rho = 2900
+ alpha = 3e-5
+
+ # dislocation viscosity
+ #disl_prof = Plagioclase_An75-Ranalli_1995
+ #disl_prof = Wet_Quarzite-Ranalli_1995
+ disl_prof = Mafic_Granulite-Ranalli_1995
+
+
+ # Elastic parameters
+ G = 3e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+
+# ------------------- Mantle lithosphere-------------------
+
+ Name = Mantle
+ ID = 3
+ rho = 3320
+ alpha = 3e-5
+
+ # dislocation viscosity
+ disl_prof = Dry_Olivine-Ranalli_1995
+
+ # Elastic parameters
+ G = 6.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3.3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Andesite -------------------
+
+ Name = magma
+ ID = 4
+ rho = 2700
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e18
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 980
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Dacite -------------------
+
+ ID = 5
+ rho = 2575
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e19
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 800
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+# End of defining material properties for all phases ----------------------------------------
+
+
+#===============================================================================
+# PETSc options
+#===============================================================================
+
+
+# SNES
+
+ -snes_npicard 5
+ -snes_max_it 200
+ -snes_rtol 1e-6
+ -snes_atol 1e-6
+ -snes_PicardSwitchToNewton_rtol 1e-7 #-7
+ #-snes_NewtonSwitchToPicard_it 1 # number of Newton iterations after which we switch back to Picard
+# -snes_monitor
+# -snes_linesearch_monitor
+
+# Jacobian solver
+ -js_ksp_type fgmres
+ -js_ksp_monitor
+ -js_ksp_max_it 30
+ -js_ksp_rtol 1e-5
+ -js_ksp_atol 1e-6
+# -js_ksp_monitor_true_residual
+
+# -its_ksp_monitor
+# -ts_ksp_monitor
+
+# Multigrid
+ -gmg_pc_mg_galerkin
+ -gmg_pc_mg_type multiplicative
+ -gmg_pc_mg_cycle_type v
+
+ -gmg_mg_levels_ksp_type richardson
+ -gmg_mg_levels_ksp_richardson_scale 0.5
+ -gmg_mg_levels_ksp_max_it 5
+ -gmg_mg_levels_pc_type jacobi
+
+ -crs_pc_factor_mat_solver_package pastix
+
+
+
+
+
+
+
diff --git a/v0.4.2/scripts/LaPalma_example.jl b/v0.4.2/scripts/LaPalma_example.jl
new file mode 100644
index 00000000..e1575367
--- /dev/null
+++ b/v0.4.2/scripts/LaPalma_example.jl
@@ -0,0 +1,125 @@
+# # Create a 3D LaMEM setup for La Palma
+#
+# ## Aim
+# In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021.
+# LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from `GeoData` to `CartData`.
+#
+#
+# ## 1. Load data
+# We will use two types of data to create the model
+# 1) Topography
+# 2) Earthquake locations
+
+# We start with loading the required packages
+using GeophysicalModelGenerator, JLD2
+using GMT
+
+# In case you managed to install GMT on your machine, you can automatically download the topography with
+Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file="@earth_relief_03s.grd")
+
+# In case you did not manage that, we have prepared a JLD2 file [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1).
+# Download it, and doublecheck that you are in the same directory as the data file with:
+pwd()
+
+# Load the data:
+Topo=load("Topo_LaPalma.jld2","Topo")
+
+# Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from [https://www.ign.es/web/ign/portal/vlc-catalogo](https://www.ign.es/web/ign/portal/vlc-catalogo)).
+# Download that [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1)
+data_all_EQ = load("EQ_Data.jld2","data_all_EQ")
+
+# Write the data to paraview with
+Write_Paraview(data_all_EQ,"data_all_EQ",PointsData=true)
+Write_Paraview(Topo,"Topo")
+
+# As earthquakes are point-wise data, you have to specify this.
+# ![LaPalma_EQTopo_GeoData](../assets/img/TopoEQs_LaPalma_GeoData.png)
+# Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where `z` is *not* pointing upwards).
+
+# ## 2. Convert data
+# In order to create model setups, it is helpful to first transfer the data to Cartesian.
+# This requires us to first determine a *projection point*, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
+proj = ProjectionPoint(Lon=-17.84, Lat=28.56)
+
+# Once this is done you can convert the topographic data to the cartesian reference frame
+EQ_cart = Convert2CartData(data_all_EQ, proj);
+Topo_cart = Convert2CartData(Topo, proj)
+
+# It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small.
+# In other cases, however, this is quite substantial (e.g., India-Asia collision zone).
+# LaMEM needs an orthogonal grid of topography, which we can create with:
+Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));
+
+# In a next step, the routine `ProjectCartData` projects a `GeoData` structure to a `CartData` struct
+Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)
+
+# Let's have a look at the data:
+Write_Paraview(EQ_cart,"EQ_cart",PointsData=true)
+Write_Paraview(Topo_LaMEM,"Topo_LaMEM")
+
+# ## 3. Create LaMEM setup
+#
+# In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and
+# the number of control volumes (elements), you want to apply in every direction.
+# The LaMEM input file can be downloaded [here](../scripts/LaPalma.dat).
+# Make sure you are in the same directory as the *.dat file & execute the following command
+Grid = ReadLaMEM_InputFile("LaPalma.dat")
+
+# The `LaMEM_grid` structure contains the number of elements in every direction and the number of markers in every cell.
+# It also contains `Grid.X`, `Grid.Y`, `Grid.Z`, which are the coordinates of each of the markers in the 3 directions.
+#
+# In a next step we need to give each of these points a `Phase` number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
+Phases = ones(Int32,size(Grid.X))*2;
+Temp = ones(Float64,size(Grid.X));
+
+# In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers
+Geotherm = 30;
+Temp = -Grid.Z.*Geotherm;
+
+# Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)
+Temp[Temp.<20] .= 20;
+Temp[Temp.>1350] .= 1350;
+
+# Because of lacking data, we have pretty much no idea where the Moho is in La Palma.
+# Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
+ind = findall( Grid.Z .< -40);
+Phases[ind] .= 3;
+
+# Everything above the free surface is assumed to be "air"
+ind = AboveSurface(Grid, Topo_cart);
+Phases[ind] .= 0;
+
+# And all "air" points that are below sea-level becomes "water"
+ind = findall( (Phases.==0) .& (Grid.Z .< 0));
+Phases[ind] .= 1;
+
+# You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small).
+# If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses.
+# We will assume the second option in our model setup.
+#
+# Looking at the seismicity, there is a swarm at around 35 km depth
+AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# A shallower one exists as well
+AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# And there might be a mid-crustal one
+AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# We can generate a 3D model setup, which must include the `Phases` and `Temp` arrays
+Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))
+Write_Paraview(Model3D,"Model3D")
+
+# The model setup looks like this
+# ![LaMEM_ModelSetup_LaPalma](../assets/img/LaMEM_ModelSetup_LaPalma.png)
+
+# We can create a LaMEM marker file from the `Model3D` setup and the (cartesian) topography
+Save_LaMEMTopography(Topo_cart, "Topography.txt")
+Save_LaMEMMarkersParallel(Model3D)
+
+# Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well.
+# If you are interested in doing this, have a look at the LaMEM [wiki](https://bitbucket.org/bkaus/lamem/wiki/Home) pages.
+
+
+#src Note: The markdown page is generated using:
+#src Literate.markdown("LaPalma_example.jl",outputdir="../man/", execute=true)
\ No newline at end of file
diff --git a/v0.4.2/scripts/Tutorial_Votemaps.jl b/v0.4.2/scripts/Tutorial_Votemaps.jl
new file mode 100644
index 00000000..597f26cc
--- /dev/null
+++ b/v0.4.2/scripts/Tutorial_Votemaps.jl
@@ -0,0 +1,77 @@
+# # Votemaps
+#
+# ## Aim
+# In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.
+#
+# ## Steps
+#
+# #### 1. Load data
+# We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to
+# [https://seafile.rlp.net/d/22b0fb85550240758552/](https://seafile.rlp.net/d/22b0fb85550240758552/)
+#
+# Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form
+# Download the corresponding *.jld2 files to the same directory
+using JLD2, GeophysicalModelGenerator
+
+Pwave_Zhao = load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp")
+PSwave_Koulakov = load("Koulakov_Europe.jld2","DataKoulakov_Alps")
+Pwave_Paffrath = load("Paffrath_Pwave.jld2","Data_set_Paffrath2021_Vp")
+
+# The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
+Pwave_Paffrath
+GeoData
+ size : (162, 130, 42)
+ lon ϵ [ -13.3019 : 35.3019]
+ lat ϵ [ 30.7638 : 61.2362]
+ depth ϵ [ -606.0385 km : 31.0385 km]
+ fields: (:dVp_Percentage, :Vp, :Resolution)
+
+PSwave_Koulakov
+ GeoData
+ size : (108, 81, 35)
+ lon ϵ [ 4.0 : 20.049999999999997]
+ lat ϵ [ 37.035928143712574 : 49.01197604790419]
+ depth ϵ [ -700.0 km : -10.0 km]
+ fields: (:dVp_percentage, :dVs_percentage)
+
+# #### 2. Creating a Votemap
+# The idea of `Votemaps` is rather simple:
+# - assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
+# - Everything that fulfills this criteria gets the number 1, everything else 0.
+# - Do the same with other tomographic models (using the same criteria or a different one).
+# - Make sure that all tomographic models are interpolated to the same grid.
+# - Sum up the 3 models.
+# - The resulting 3D map will have the number `3` at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
+#
+# The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
+#
+# So how do we create Votemaps?
+# Doing this is rather simple:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_percentage>2.0","dVp_Percentage>2.0"], dims=(100,100,100))
+
+# This will look at the common `lon`,`lat`,`depth` ranges between all 3 models, interpret each of the models to a common grid of size `(100,100,100)` and apply each of the criteria specified
+# The resulting `GeoData` struct looks like:
+GeoData
+ size : (100, 100, 100)
+ lon ϵ [ 4.0 : 18.0]
+ lat ϵ [ 38.0 : 49.01197604790419]
+ depth ϵ [ -606.0385 km : -10.0 km]
+ fields: (:VoteMap,)
+
+# And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
+Write_Paraview(Data_VoteMap, "VoteMap_Alps")
+
+# In paraview, this gives
+# ![Tutorial_VoteMap](../assets/img/Tutorial_VoteMap.png)
+
+# You can ofcourse argue that newer tomographic models include more data & should therefore count more
+# A simple way to take that into account is to list the model twice:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_Percentage>3.0", "dVp_percentage>2.0","dVp_Percentage>2.0"],
+ dims=(100,100,100))
+
+# Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
+
+
+
diff --git a/v0.4.2/search/index.html b/v0.4.2/search/index.html
new file mode 100644
index 00000000..2571b52e
--- /dev/null
+++ b/v0.4.2/search/index.html
@@ -0,0 +1,2 @@
+
+Search · GeophysicalModelGenerator.jl
Loading search...
Settings
This document was generated with Documenter.jl on Friday 24 June 2022. Using Julia version 1.7.3.
diff --git a/v0.4.2/search_index.js b/v0.4.2/search_index.js
new file mode 100644
index 00000000..e5b1948e
--- /dev/null
+++ b/v0.4.2/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData\nGeophysicalModelGenerator.Screenshot_To_UTMData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_UTMData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_UTMData","text":"Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true)\n\nDoes the same as Screenshot_To_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tutorial_local_Flegrei/#Km-scale-volcano-tutorial-using-cartesian-coordinates","page":"Kilometer-scale volcano","title":"Km-scale volcano tutorial using cartesian coordinates","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#Goal","page":"Kilometer-scale volcano","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Two shape files containing coastline and faults:\nVilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508\nEarthquake data for two volcanic unrests, in 1983-84 and 2005-2016:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7\nDe Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817\nTravel time tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x\nAmbient noise tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x","category":"page"},{"location":"man/tutorial_local_Flegrei/#Steps","page":"Kilometer-scale volcano","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#.-Download-all-data-for-region","page":"Kilometer-scale volcano","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Make sure that you are in the unzipped directory.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Geomorphology","page":"Kilometer-scale volcano","title":"2. Geomorphology","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Load both the the shape (.shp) files contained in \"./Geomorphology/*.shp\" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Geomorphology)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Earthquakes","page":"Kilometer-scale volcano","title":"3. Earthquakes","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Now let's plot earthquake data provided as text files. Start loading the data contained in \"./SeismicLocations/*.txt\". The first column gives us a temporal marker we can use to plot earthquakes in different periods.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Glob, GeoStats\njulia> data_80s = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> data_00s = readdlm(\"SeismicLocations/Seismicity_UTM_2005_2016.txt\", ' ', skipstart=0, header=false);\njulia> data = vcat(data_80s,data_00s) \njulia> time = data[:,1];\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> EQ_Data_Cart = CartData(WE,SN,depth,(Depth=depth * m,Time=time * yr,));\njulia> Write_Paraview(EQ_Data_Cart, \"CF_Earthquakes_Cartesian\", PointsData=true)\njulia> EQ_Data_UTM = UTMData(WE, SN, depth, 33, true, (Depth=depth * m,Time=time * yr,));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,EQ_Data_UTM)\njulia> Write_Paraview(Data_set_UTM, \"CF_Earthquakes_UTM\", PointsData=true)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Save in paraview with both cartesian and UTM formats. The final seismicity map looks like this:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_seismicity)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"The colour scale distinguishes earthquakes of different decades. Notice the progressive migration of recent seismicity (black dots) towards East.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Velocity-model","page":"Kilometer-scale volcano","title":"4. Velocity model","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in \"./TravelTmeTomography/modvPS.dat\" for both cartesian and UTM coordinates.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"TravelTimeTomography/modvPS.dat\", '\\t', Float64, skipstart=0, header=false);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vp = data[:,4];\njulia> Vs = data[:,5];\njulia> VpVs = data[:,6];\njulia> resolution = (length(unique(depth)), length(unique(SN)), length(unique(WE)))\njulia> dim_perm = [3 2 1]\njulia> we = permutedims(reshape(WE, resolution), dim_perm);\njulia> sn = permutedims(reshape(SN, resolution), dim_perm);\njulia> depth = permutedims(reshape(depth, resolution), dim_perm);\njulia> Vp3d = permutedims(reshape(Vp, resolution), dim_perm);\njulia> Vs3d = permutedims(reshape(Vs, resolution), dim_perm);\njulia> Vp_Vs3d = permutedims(reshape(VpVs, resolution), dim_perm);\njulia> Data_set_Cartesian = CartData(we, sn, depth, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Write_Paraview(Data_set_Cartesian, \"CF_Velocity_Cartesian\")\njulia> Data_set = UTMData(we, sn, depth, 33, true, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,Data_set)\njulia> Write_Paraview(Data_set_UTM, \"CF_Velocity_UTM\")","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Including the Vp/Vs model in the previous Paraview file workspace:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_VpVs)","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Horizontal-slices-of-shear-velocity-on-irregular-grid","page":"Kilometer-scale volcano","title":"5. Horizontal slices of shear velocity on irregular grid","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files \"./NoiseTomography/*.txt\". We read them consecutively in a \"for\" loop:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> list_files = glob(\"AmbientNoiseTomography/*.txt\");\njulia> li = size(list_files, 1);\njulia> for i = 1:li\njulia> nameFile = list_files[i];\njulia> name_vts = name_vts[24:26];\njulia> data = readdlm(nameFile, '\\t', Float64);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"However these models are too wide, so it is better to constrain them:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );\njulia> WE = WE[ind];\njulia> SN = SN[ind];\njulia> depth = depth[ind];\njulia> Vs = Vs[ind];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Also, nodes are irregular, hence we create a 3D regular UTM:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> l = length(WE);\njulia> n_WE = minimum(WE):100:maximum(WE);\njulia> n_SN = minimum(SN):100:maximum(SN);\njulia> we, sn, Depth = XYZGrid(n_WE, n_SN, depth[1]);\njulia> Vs_3D = zeros(size(Depth));\njulia> Cgrid = GeoStats.CartesianGrid((size(we, 1), size(we, 2)), (minimum(we), minimum(sn)), (we[2,2,1] - we[1,1,1], sn[2,2,1] - sn[1,1,1]))\njulia> coord = PointSet([WE[:]'; SN[:]']);\njulia> Geo = georef((Vs = Vs[:],), coord);\njulia> P = EstimationProblem(Geo, Cgrid, :Vs);\njulia> S = IDW(:Vs => (;neighbors=2));\njulia> sol = solve(P, S);\njulia> sol_Vs = values(sol).Vs;\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)));\njulia> Vs_3D[:,:,1] = Vs_2D;\njulia> Data_set_Cart = CartData(we, sn, Depth, (Vs = Vs_3D * (km / s),))\njulia> Write_Paraview(Data_set_Cart, \"CF_Noise\" * name_vts * \"_Cartesian\")\njulia> Data_set = UTMData(we, sn, Depth, 33, true, (Vs = Vs_3D*(km / s),));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData, Data_set);\njulia> Write_Paraview(Data_set_UTM, \"CF_Noise_UTM_\"*name_vts)\njulia> end","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This is one of the horizontal sections created by the code in the previous model in both reference systems:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Noise)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!\nGeophysicalModelGenerator.Convert2UTMzone\nGeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ImportTopo\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.DrapeOnTopo\nGeophysicalModelGenerator.LithostaticPressure!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(Volume::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData \n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::GeoData, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\n\n\n\n\nInterpolateDataFields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values. \n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData \n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf. nex\n\nExample\n\njulia> Data\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n ParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.DrapeOnTopo","page":"Tools","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"Topo = DrapeOnTopo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo \n\n\n\n\n\nDrapeOnTopo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography \n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.LithostaticPressure!","page":"Tools","title":"GeophysicalModelGenerator.LithostaticPressure!","text":"LithostaticPressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max], grid=true);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Julia-script","page":"3D seismic tomography from ASCII","title":"Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.UTMData\nGeophysicalModelGenerator.ParaviewData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid\nGeophysicalModelGenerator.XYZGrid\nGeophysicalModelGenerator.ProjectionPoint","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> Lat = 1.0:3:10.0;\njulia> Lon = 11.0:4:20.0;\njulia> Depth = (-20:5:-10)*km;\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);\njulia> Lon3D\n3×4×3 Array{Float64, 3}:\n[:, :, 1] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 2] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 3] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\njulia> Lat3D\n 3×4×3 Array{Float64, 3}:\n [:, :, 1] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 2] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 3] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\njulia> Depth3D\n 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:\n [:, :, 1] =\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n \n [:, :, 2] =\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n \n [:, :, 3] =\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\njulia> Data = zeros(size(Lon3D));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,)) \nGeoData \n size : (3, 4, 3)\n lon ϵ [ 11.0 : 19.0]\n lat ϵ [ 1.0 : 10.0]\n depth ϵ [ -20.0 km : -10.0 km]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.UTMData","page":"Data Structures","title":"GeophysicalModelGenerator.UTMData","text":"UTMData(EW::Any, NS:Any, depth::GeoUnit, UTMZone::Int, NorthernHemisphere=true, fields::NamedTuple)\n\nData structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.\n\ndepth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> ew = 422123.0:100:433623.0\njulia> ns = 4.514137e6:100:4.523637e6\njulia> depth = -5400:250:600\njulia> EW,NS,Depth = XYZGrid(ew, ns, depth);\njulia> Data = ustrip.(Depth);\njulia> Data_set = UTMData(EW,NS,Depth,33, true, (FakeData=Data,Data2=Data.+1.)) \nUTMData \n UTM zone : 33-33 North\n size : (116, 96, 25)\n EW ϵ [ 422123.0 : 433623.0]\n NS ϵ [ 4.514137e6 : 4.523637e6]\n depth ϵ [ -5400.0 m : 600.0 m]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nIf you wish, you can convert this from UTMData to GeoData with\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nwhich would allow visualizing this in paraview in the usual manner:\n\njulia> Write_Paraview(Data_set1, \"Data_set1\")\n1-element Vector{String}:\n \"Data_set1.vts\"\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.ParaviewData","page":"Data Structures","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(ParaviewData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::Any, y::Any, z::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers\n\nx,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nx,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData \n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nCartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with\n\njulia> Write_Paraview(Data_set, \"Data_set\")\n1-element Vector{String}:\n \"Data_set.vts\"\n\nIf you wish, you can convert this to UTMData (which will simply convert the )\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields: (:FakeData, :Data2)\n\nwhich would allow visualizing this in paraview in the usual manner:\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.ProjectionPoint","page":"Data Structures","title":"GeophysicalModelGenerator.ProjectionPoint","text":"struct ProjectionPoint\n Lon :: Float64\n Lat :: Float64\n EW :: Float64\n NS :: Float64\n zone :: Integer\n isnorth :: Bool\nend\n\nStructure that holds the coordinates of a point that is used to project a data set from Lon/Lat to a Cartesian grid and vice-versa.\n\n\n\n\n\n","category":"type"},{"location":"man/tutorial_time_Seismicity/#How-to-create-a-movie-to-show-seismic-distribution-through-time","page":"Create movies","title":"How to create a movie to show seismic distribution through time","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#Goal","page":"Create movies","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Earthquake data for the 1983-84 unrest:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7","category":"page"},{"location":"man/tutorial_time_Seismicity/#Steps","page":"Create movies","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#.-Download-all-data-for-region","page":"Create movies","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_1)","category":"page"},{"location":"man/tutorial_time_Seismicity/#.-Earthquakes-in-movie","page":"Create movies","title":"2. Earthquakes in movie","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Dates\njulia> p2 = @__FILE__;\njulia> p2last = findlast(\"/\",p2);\njulia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);\njulia> output_path = string(p3,\"/\");\njulia> movie = Movie_Paraview(name=string(p3,\"/TemporalSeismicity\"), Initialize=true);\njulia> if isdir(string(p3,\"/TemporalSeismicity\"))==0\njulia> mkdir(string(p3,\"/TemporalSeismicity\"));\njulia> end\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> data = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> l = length(data[:,1]);\njulia> dates = Date.(zeros(l,1))\njulia> for i = 1:l\njulia> df = DateFormat(\"yyyymmdd\");\njulia> t1 = string(\"19\",@sprintf(\"%5.o\", data[i,1]));\njulia> t2 = Date(t1[1:8],df);\njulia> dates[i,1] = t2;\njulia> end\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> dates_num = dates - dates[1];\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> nt = 50;\njulia> dt = Dates.Day(nt);\njulia> t = minimum(dates):dt:maximum(dates);\njulia> for itime = 1:length(t)-1\njulia> name = string(p3,\"/TemporalSeismicity/\", string(itime));\njulia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);\njulia> we = WE[tt];\njulia> sn = SN[tt];\njulia> Depth1 = depth[tt];\njulia> DN = dates_num[tt];\njulia> label_time = Dates.value(DN[end]);\njulia> if size(tt,1)>1\njulia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));\njulia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);\njulia> end\njulia>end\njulia>Movie_Paraview(pvd=movie, Finalize=true)\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_PVD)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_Movie)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section & create VTS file\n3. Read data of a mapview & create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 4.65, 45.73, -400.0)\njulia> Corner_UpperRight = (17.23, 43.80, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = (4.65 , 45.73 , -400.0 )\n └ lower right = (17.23 , 43.8 , -400.0 )\n └ upper left = (4.65 , 45.73 , 0.0 )\n └ upper right = (17.23 , 43.8 , 0.0 )\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 4.6499999999999995 : 17.230000000000004]\n lat ϵ [ 43.79999999999999 : 45.730000000000004]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/visualise/#Visualisation","page":"Visualisation","title":"Visualisation","text":"","category":"section"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> using GeophysicalModelGenerator, GLMakie\njulia> using GMT, JLD2","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> ;\nshell> cd ~/Downloads/Zhao_etal_2016_data/ ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Now you can use the backspace key to return to the REPL, where we will load the data","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Data = JLD2.load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\"); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"At this stage you can look at it with","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Note that this tends to take a while, the first time you do this (faster afterwards).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Let's add topography to the plot as well, which requires us to first load that:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Topo = ImportTopo([0,18,38,52], file=\"@earth_relief_01m.grd\");\njulia> Visualise(Data, Topography=Topo); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Which will look like: (Image: Tutorial_Visualize)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> p=ProjectionPoint(Lon=10, Lat=45)\nProjectionPoint(45.0, 10.0, 578815.302916711, 4.983436768349297e6, 32, true)\njulia> Data_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,-1000:10:-1));\njulia> Topo_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,0));\njulia> Topo_Cart = ProjectCartData(Topo_Cart, Topo, p)\nCartData \n size : (121, 121, 1)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -3.6270262031545473 : 3.654942280296281]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Data_Cart = ProjectCartData(Data_Cart, Data, p)\nCartData \n size : (121, 121, 100)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -1000.0 : -10.0]\n fields : (:dVp_Percentage,)\n attributes: [\"note\"]","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"And once we have done that, you can visualize the data in the same way:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data_Cart, Topography=Topo_Cart)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"GeophysicalModelGenerator.Visualise","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview\nGeophysicalModelGenerator.Movie_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"pvd = Write_Paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a structure with Geodatato a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), setPointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to passtimeandpvd`\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\nWrite_Paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\nWrite_Paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"function"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Movie_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Movie_Paraview","text":"pvd = Movie_Paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = Movie_Paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = Write_Paraview(Data, name, pvd=movie, time=itime)\nend\nMovie_Paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"function"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"EditURL = \"/Tutorial_Votemaps.jl\"","category":"page"},{"location":"man/Tutorial_Votemaps/#Votemaps","page":"VoteMaps","title":"Votemaps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#Aim","page":"VoteMaps","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.","category":"page"},{"location":"man/Tutorial_Votemaps/#Steps","page":"VoteMaps","title":"Steps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#.-Load-data","page":"VoteMaps","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to https://seafile.rlp.net/d/22b0fb85550240758552/","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"using JLD2, GeophysicalModelGenerator\n\nPwave_Zhao = load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\")\nPSwave_Koulakov = load(\"Koulakov_Europe.jld2\",\"DataKoulakov_Alps\")\nPwave_Paffrath = load(\"Paffrath_Pwave.jld2\",\"Data_set_Paffrath2021_Vp\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Pwave_Paffrath\nGeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 km : 31.0385 km]\n fields: (:dVp_Percentage, :Vp, :Resolution)\n\nPSwave_Koulakov\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)","category":"page"},{"location":"man/Tutorial_Votemaps/#.-Creating-a-Votemap","page":"VoteMaps","title":"2. Creating a Votemap","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The idea of Votemaps is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)\nEverything that fulfills this criteria gets the number 1, everything else 0.\nDo the same with other tomographic models (using the same criteria or a different one).\nMake sure that all tomographic models are interpolated to the same grid.\nSum up the 3 models.\nThe resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"So how do we create Votemaps? Doing this is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"], dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"GeoData\n size : (100, 100, 100)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -606.0385 km : -10.0 km]\n fields: (:VoteMap,)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Write_Paraview(Data_VoteMap, \"VoteMap_Alps\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In paraview, this gives (Image: Tutorial_VoteMap)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_Percentage>3.0\", \"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"],\n dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/projection/#Projecting-and-converting-data","page":"Projection","title":"Projecting & converting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid). ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.","category":"page"},{"location":"man/projection/#.-Converting","page":"Projection","title":"1. Converting","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Converting from one coordinate system to the other is straightforward. Let's use Europe as an example:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo(lon = [-10, 45], lat=[25, 50], file=\"@earth_relief_20m\")\nGeoData \n size : (165, 75, 1)\n lon ϵ [ -10.0 : 44.666666666666664]\n lat ϵ [ 25.0 : 49.666666666666664]\n depth ϵ [ -4.9855 km : 3.123 km]\n fields: (:Topography,)\njulia> Write_Paraview(Topo,\"Topo\")\nSaved file: Topo.vts","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"The result is shown on the globe as: (Image: Topo_Europe_GeoData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can convert this to UTM zone as:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert(UTMData, Topo)\nUTMData \n UTM zone : 29-38 North\n size : (165, 75, 1)\n EW ϵ [ 197181.31221507967 : 769155.4572884373]\n NS ϵ [ 2.7649477474783654e6 : 5.505892073781423e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> p=ProjectionPoint(Lon=17.3, Lat=37.5)\nProjectionPoint(37.5, 17.3, 703311.4380385976, 4.152826288024972e6, 33, true)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Projecting the GeoData set using this projection point is done with:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Convert2UTMzone(Topo,p)\nUTMData \n UTM zone : 33-33 North\n size : (165, 75, 1)\n EW ϵ [ -2.0750691599137965e6 : 3.581351293385453e6]\n NS ϵ [ 2.7649477474783654e6 : 5.938114212160672e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is now in UTM Data (in meters), it is distorted. (Image: Topo_Europe_UTMData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Often it is more convenient to have this in CartData, which is done in a similar manner:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart = Convert2CartData(Topo,p)\nCartData \n size : (165, 75, 1)\n x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]\n y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]\n z ϵ [ -4.9855 km : 3.123 km]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"This shows that the model is ~5600 by 3000 km. (Image: Topo_Europe_CartData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal. ","category":"page"},{"location":"man/projection/#.-Projecting-data","page":"Projection","title":"2. Projecting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"For use with LaMEM, you would need an orthogonal cartesian grid. From the last command above we get some idea on the area, so we can create this:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = CartData(XYZGrid(-2000:20:2000,-1000:20:1000,0))\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Next, we can project the topographic data (in GeoData format) on this orthogonal grid","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = ProjectCartData(Topo_Cart_orth, Topo, p)\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ -4.485650671162607 km : 2.5909655318121865 km]\n fields : (:Topography,)\njulia> Write_Paraview(Topo_Cart_orth,\"Topo_Cart_orth\"); ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"(Image: Topo_Europe_CartData_Proj) So this interpolates the topographic data from the GeoData to the orthogonal cartesian grid (which can be used with LaMEM, for example).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can do similar projections with full 3D data sets or pointwise data. ","category":"page"},{"location":"man/projection/#.-List-of-functions","page":"Projection","title":"3. List of functions","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"GeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.Convert2UTMzone","category":"page"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2CartData","page":"Projection","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\nConvert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.ProjectCartData","page":"Projection","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = ProjectCartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2UTMzone","page":"Projection","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\nConvert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_UTM/#Read-in-UTM-data","page":"Read UTM data","title":"Read in UTM data","text":"","category":"section"},{"location":"man/tutorial_UTM/#Goal","page":"Read UTM data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004","category":"page"},{"location":"man/tutorial_UTM/#Steps","page":"Read UTM data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_UTM/#.-Download-and-import-UTM-data:","page":"Read UTM data","title":"1. Download and import UTM data:","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)\t\t\t\t\t\n# when using the data please cite as: \t\t\t\t\t\n# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004\nX COORD (UTM Zone 32N)\tY COORD (UTM Zone 32N)\tTOP (m.a.s.l)\tTHICKNESS (m)\tDENSITY (Kg/m3)\n286635\t4898615\t-24823.2533\t70418.125\t3305\n286635\t4918615\t-25443.48901\t69410.01563\t3305\n286635\t4938615\t-28025.24511\t66402.49219\t3305\n286635\t4958615\t-32278.13135\t61663.48438\t3305\n286635\t4978615\t-35885.5625\t57459.14063\t3305\n286635\t4998615\t-37270.9812\t55318.71094\t3305\n286635\t5018615\t-36134.30481\t55497.16406\t3305\n286635\t5038615\t-34866.0697\t55555.41406\t3305","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data=readdlm(\"2019-004_Spooner_Lithospheric Mantle.txt\",skipstart=4)\n1023×5 Matrix{Float64}:\n 286635.0 4.89862e6 -24823.3 70418.1 3305.0\n 286635.0 4.91862e6 -25443.5 69410.0 3305.0\n 286635.0 4.93862e6 -28025.2 66402.5 3305.0\n 286635.0 4.95862e6 -32278.1 61663.5 3305.0\n ⋮ \n 926635.0 5.45862e6 -35302.7 83215.6 3335.0\n 926635.0 5.47862e6 -34908.6 84203.0 3335.0\n 926635.0 5.49862e6 -34652.4 85398.3 3335.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> ew, ns, depth, thick, rho = data[:,1], data[:,2], data[:,3], data[:,4], data[:,5];","category":"page"},{"location":"man/tutorial_UTM/#.-Check-and-reshape-vertical-velocity","page":"Read UTM data","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> res = ( length(unique(ns)), length(unique(ew)), 1)\njulia> EW = reshape(ew,res) \njulia> NS = reshape(ns,res)\njulia> Depth = reshape(depth,res)\njulia> T = reshape(thick,res)\njulia> Rho = reshape(rho,res)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can examine EW: ","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW\n31×33×1 Array{Float64, 3}:\n[:, :, 1] =\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n ⋮ ⋮ ⋱ ⋮ \n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW = permutedims(EW,[2 1 3]) \njulia> NS = permutedims(NS,[2 1 3]) \njulia> Depth = permutedims(Depth,[2 1 3]) \njulia> T = permutedims(T,[2 1 3]) \njulia> Rho = permutedims(Rho,[2 1 3]) ","category":"page"},{"location":"man/tutorial_UTM/#.-Create-UTMData-structure","page":"Read UTM data","title":"3. Create UTMData structure","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can add the data to the UTMData structure. In this, we use the information that the UTM zone was 32 North.","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM = UTMData(EW,NS,Depth,32, true, (Thickness=T/1e3*km, Density=Rho*kg/m^3 ))\nUTMData \n UTM zone : 32-32 North\n size : (33, 31, 1)\n EW ϵ [ 286635.0 : 926635.0]\n NS ϵ [ 4.898615e6 : 5.498615e6]\n depth ϵ [ -52579.56788 m : -20873.400850000003 m]\n fields : (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/#.-Saving-and-plotting-in-Paraview","page":"Read UTM data","title":"4. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can transfer this into a GeoData structure as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM_lonlat = convert(GeoData,Data_LM)\nGeoData \n size : (33, 31, 1)\n lon ϵ [ 6.046903388679526 : 14.892535147436673]\n lat ϵ [ 44.11618022783332 : 49.64004892531006]\n depth ϵ [ -52.57956788 km : -20.873400850000003 km]\n fields: (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"and save it to Paraview in the usual way","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Write_Paraview(Data_LM_lonlat, \"Data_LM_lonlat\")","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Opening and plotting the vertical field gives: (Image: Tutorial_UTM)","category":"page"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nAdd lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.Save_LaMEMTopography\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.ReadData_PVTR\nGeophysicalModelGenerator.AddBox!\nGeophysicalModelGenerator.AddSphere!\nGeophysicalModelGenerator.AddEllipsoid!\nGeophysicalModelGenerator.AddCylinder!\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.CreatePartitioningFile","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file)\n\nParses a LaMEM input file and stores grid information in the Grid structure.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\") \nLaMEM Grid: \nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMTopography","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMTopography","text":"Save_LaMEMTopography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::ParaviewData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddBox!","page":"LaMEM","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::LaMEM_grid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddSphere!","page":"LaMEM","title":"GeophysicalModelGenerator.AddSphere!","text":"AddSphere!(Phase, Temp, Grid::LaMEM_grid; cen=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddSphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddEllipsoid!","page":"LaMEM","title":"GeophysicalModelGenerator.AddEllipsoid!","text":"AddEllipsoid!(Phase, Temp, Grid::LaMEM_grid; cen=Tuple{3}, axes=Tuple{3},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddEllipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddCylinder!","page":"LaMEM","title":"GeophysicalModelGenerator.AddCylinder!","text":"AddCylinder!(Phase, Temp, Grid::LaMEM_grid; base=Tuple{3}, cap=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddCylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantTemp","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LinearTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LinearTemp","text":"LinearTemp(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"LaMEM","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCoolingTemp(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.SpreadingRateTemp","page":"LaMEM","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantPhase","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericPhases","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 30], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : the thickness of the layers from top downwards\nPhases : the phases of the layers from top down. Note that this array \nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab is set to Phases[end]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.CreatePartitioningFile","page":"LaMEM","title":"GeophysicalModelGenerator.CreatePartitioningFile","text":"CreatePartitioningFile(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\")\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded. ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo([4,20,37,49], file=\"@earth_relief_01m.grd\")\nGeoData \n size : (960, 720, 1)\n lon ϵ [ 4.0 : 19.983333333333334]\n lat ϵ [ 37.0 : 48.983333333333334]\n depth ϵ [ -3.8725 km : 4.2495 km]\n fields: (:Topography,)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area. ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Write_Paraview(Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EditURL = \"/LaPalma_example.jl\"","category":"page"},{"location":"man/LaPalma_example/#Create-a-3D-LaMEM-setup-for-La-Palma","page":"Generating LaMEM model","title":"Create a 3D LaMEM setup for La Palma","text":"","category":"section"},{"location":"man/LaPalma_example/#Aim","page":"Generating LaMEM model","title":"Aim","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.","category":"page"},{"location":"man/LaPalma_example/#.-Load-data","page":"Generating LaMEM model","title":"1. Load data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We will use two types of data to create the model","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topography\nEarthquake locations","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We start with loading the required packages","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"using GeophysicalModelGenerator, JLD2\nusing GMT","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you managed to install GMT on your machine, you can automatically download the topography with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file=\"@earth_relief_03s.grd\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"pwd()","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"\"/Users/kausb/.julia/dev/GeophysicalModelGenerator/docs/src/scripts\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Load the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo=load(\"Topo_LaPalma.jld2\",\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from https://www.ign.es/web/ign/portal/vlc-catalogo). Download that here","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"data_all_EQ = load(\"EQ_Data.jld2\",\"data_all_EQ\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (6045,)\n lon ϵ [ -18.0341 : -17.6671]\n lat ϵ [ 28.3102 : 28.8144]\n depth ϵ [ NaN km : NaN km]\n fields: (:Magnitude, :TimeSinceJan1_2021)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write the data to paraview with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(data_all_EQ,\"data_all_EQ\",PointsData=true)\nWrite_Paraview(Topo,\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: data_all_EQ.vtu\nSaved file: Topo.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"As earthquakes are point-wise data, you have to specify this. (Image: LaPalma_EQTopo_GeoData) Note that this data is not in \"easy\" coordinates (see coordinate axis in the plot, where z is not pointing upwards).","category":"page"},{"location":"man/LaPalma_example/#.-Convert-data","page":"Generating LaMEM model","title":"2. Convert data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"proj = ProjectionPoint(Lon=-17.84, Lat=28.56)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ProjectionPoint(28.56, -17.84, 222158.69478000276, 3.1625327286383654e6, 28, true)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Once this is done you can convert the topographic data to the cartesian reference frame","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EQ_cart = Convert2CartData(data_all_EQ, proj);\nTopo_cart = Convert2CartData(Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (1921, 1441, 1)\n x ϵ [ -86.09445705828863 km : 73.67229892155609 km]\n y ϵ [ -63.5531883197492 km : 73.28446155584604 km]\n z ϵ [ -4.38297802734375 km : 2.414 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, the routine ProjectCartData projects a GeoData structure to a CartData struct","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (701, 651, 1)\n x ϵ [ -70.0 km : 70.0 km]\n y ϵ [ -60.0 km : 70.0 km]\n z ϵ [ -4.29541702331831 km : 2.3840784607152257 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Let's have a look at the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(EQ_cart,\"EQ_cart\",PointsData=true)\nWrite_Paraview(Topo_LaMEM,\"Topo_LaMEM\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: EQ_cart.vtu\nSaved file: Topo_LaMEM.vts\n","category":"page"},{"location":"man/LaPalma_example/#.-Create-LaMEM-setup","page":"Generating LaMEM model","title":"3. Create LaMEM setup","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Grid = ReadLaMEM_InputFile(\"LaPalma.dat\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"LaMEM Grid: \n nel : (64, 64, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 192, 192)\n x ϵ [-50.0 : 50.0]\n y ϵ [-40.0 : 40.0]\n z ϵ [-80.0 : 15.0]\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Phases = ones(Int32,size(Grid.X))*2;\nTemp = ones(Float64,size(Grid.X));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Geotherm = 30;\nTemp = -Grid.Z.*Geotherm;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Temp[Temp.<20] .= 20;\nTemp[Temp.>1350] .= 1350;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to \"mantle\":","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( Grid.Z .< -40);\nPhases[ind] .= 3;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Everything above the free surface is assumed to be \"air\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = AboveSurface(Grid, Topo_cart);\nPhases[ind] .= 0;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And all \"air\" points that are below sea-level becomes \"water\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( (Phases.==0) .& (Grid.Z .< 0));\nPhases[ind] .= 1;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Looking at the seismicity, there is a swarm at around 35 km depth","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"A shallower one exists as well","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And there might be a mid-crustal one","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can generate a 3D model setup, which must include the Phases and Temp arrays","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\nWrite_Paraview(Model3D,\"Model3D\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: Model3D.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The model setup looks like this (Image: LaMEM_ModelSetup_LaPalma)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can create a LaMEM marker file from the Model3D setup and the (cartesian) topography","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Save_LaMEMTopography(Topo_cart, \"Topography.txt\")\nSave_LaMEMMarkersParallel(Model3D)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Written LaMEM topography file: Topography.txt\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.\nCreate movies for representation of earthquake or wave propagation.\nCreate geodynamic input models (for LaMEM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.4.2/siteinfo.js b/v0.4.2/siteinfo.js
new file mode 100644
index 00000000..c928059b
--- /dev/null
+++ b/v0.4.2/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.4.2";
diff --git a/v0.4.7/assets/documenter.js b/v0.4.7/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.4.7/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.4.7/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png b/v0.4.7/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.4.7/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png differ
diff --git a/v0.4.7/assets/img/Digitizer_1.png b/v0.4.7/assets/img/Digitizer_1.png
new file mode 100644
index 00000000..5f731462
Binary files /dev/null and b/v0.4.7/assets/img/Digitizer_1.png differ
diff --git a/v0.4.7/assets/img/Digitizer_2.png b/v0.4.7/assets/img/Digitizer_2.png
new file mode 100644
index 00000000..59837df0
Binary files /dev/null and b/v0.4.7/assets/img/Digitizer_2.png differ
diff --git a/v0.4.7/assets/img/Digitizer_3.png b/v0.4.7/assets/img/Digitizer_3.png
new file mode 100644
index 00000000..24725997
Binary files /dev/null and b/v0.4.7/assets/img/Digitizer_3.png differ
diff --git a/v0.4.7/assets/img/Fig13_mapview.png b/v0.4.7/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.4.7/assets/img/Fig13_mapview.png differ
diff --git a/v0.4.7/assets/img/Flegrei_Geomorphology.png b/v0.4.7/assets/img/Flegrei_Geomorphology.png
new file mode 100644
index 00000000..c145ff48
Binary files /dev/null and b/v0.4.7/assets/img/Flegrei_Geomorphology.png differ
diff --git a/v0.4.7/assets/img/Flegrei_Noise.png b/v0.4.7/assets/img/Flegrei_Noise.png
new file mode 100644
index 00000000..6150ac2e
Binary files /dev/null and b/v0.4.7/assets/img/Flegrei_Noise.png differ
diff --git a/v0.4.7/assets/img/Flegrei_Seismicity.png b/v0.4.7/assets/img/Flegrei_Seismicity.png
new file mode 100644
index 00000000..30675ff4
Binary files /dev/null and b/v0.4.7/assets/img/Flegrei_Seismicity.png differ
diff --git a/v0.4.7/assets/img/Flegrei_VpVs.png b/v0.4.7/assets/img/Flegrei_VpVs.png
new file mode 100644
index 00000000..a4436fc6
Binary files /dev/null and b/v0.4.7/assets/img/Flegrei_VpVs.png differ
diff --git a/v0.4.7/assets/img/LaMEM_ModelSetup_LaPalma.png b/v0.4.7/assets/img/LaMEM_ModelSetup_LaPalma.png
new file mode 100644
index 00000000..863a18a8
Binary files /dev/null and b/v0.4.7/assets/img/LaMEM_ModelSetup_LaPalma.png differ
diff --git a/v0.4.7/assets/img/Lippitsch_Fig13a.png b/v0.4.7/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.4.7/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.4.7/assets/img/Readme_pic.png b/v0.4.7/assets/img/Readme_pic.png
new file mode 100644
index 00000000..61fd8a00
Binary files /dev/null and b/v0.4.7/assets/img/Readme_pic.png differ
diff --git a/v0.4.7/assets/img/TopoEQs_LaPalma_GeoData.png b/v0.4.7/assets/img/TopoEQs_LaPalma_GeoData.png
new file mode 100644
index 00000000..9ac618c6
Binary files /dev/null and b/v0.4.7/assets/img/TopoEQs_LaPalma_GeoData.png differ
diff --git a/v0.4.7/assets/img/Topo_Europe_CartData.png b/v0.4.7/assets/img/Topo_Europe_CartData.png
new file mode 100644
index 00000000..29f75dd0
Binary files /dev/null and b/v0.4.7/assets/img/Topo_Europe_CartData.png differ
diff --git a/v0.4.7/assets/img/Topo_Europe_CartData_Proj.png b/v0.4.7/assets/img/Topo_Europe_CartData_Proj.png
new file mode 100644
index 00000000..f79fdf09
Binary files /dev/null and b/v0.4.7/assets/img/Topo_Europe_CartData_Proj.png differ
diff --git a/v0.4.7/assets/img/Topo_Europe_GeoData.png b/v0.4.7/assets/img/Topo_Europe_GeoData.png
new file mode 100644
index 00000000..d4ef347c
Binary files /dev/null and b/v0.4.7/assets/img/Topo_Europe_GeoData.png differ
diff --git a/v0.4.7/assets/img/Topo_Europe_UTMData.png b/v0.4.7/assets/img/Topo_Europe_UTMData.png
new file mode 100644
index 00000000..3dc6756e
Binary files /dev/null and b/v0.4.7/assets/img/Topo_Europe_UTMData.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Coastlines.png b/v0.4.7/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GMT_topography.png b/v0.4.7/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GPS_1.png b/v0.4.7/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GPS_2.png b/v0.4.7/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GPS_3.png b/v0.4.7/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.4.7/assets/img/Tutorial_GPS_4.png b/v0.4.7/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.4.7/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.4.7/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.4.7/assets/img/Tutorial_SeismicityTime_1.png b/v0.4.7/assets/img/Tutorial_SeismicityTime_1.png
new file mode 100644
index 00000000..69b25f21
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_SeismicityTime_1.png differ
diff --git a/v0.4.7/assets/img/Tutorial_SeismicityTime_2.png b/v0.4.7/assets/img/Tutorial_SeismicityTime_2.png
new file mode 100644
index 00000000..09252190
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_SeismicityTime_2.png differ
diff --git a/v0.4.7/assets/img/Tutorial_SeismicityTime_3.mov b/v0.4.7/assets/img/Tutorial_SeismicityTime_3.mov
new file mode 100644
index 00000000..04ed003e
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_SeismicityTime_3.mov differ
diff --git a/v0.4.7/assets/img/Tutorial_UTM.png b/v0.4.7/assets/img/Tutorial_UTM.png
new file mode 100644
index 00000000..271b680f
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_UTM.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Visualize.png b/v0.4.7/assets/img/Tutorial_Visualize.png
new file mode 100644
index 00000000..df919f45
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Visualize.png differ
diff --git a/v0.4.7/assets/img/Tutorial_VoteMap.png b/v0.4.7/assets/img/Tutorial_VoteMap.png
new file mode 100644
index 00000000..2e318e6a
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_VoteMap.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.4.7/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.4.7/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.4.7/assets/search.js b/v0.4.7/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.4.7/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.
Create movies for representation of earthquake or wave propagation.
Create geodynamic input models (for LaMEM)
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
diff --git a/v0.4.7/man/LaPalma_example/index.html b/v0.4.7/man/LaPalma_example/index.html
new file mode 100644
index 00000000..7f2682cf
--- /dev/null
+++ b/v0.4.7/man/LaPalma_example/index.html
@@ -0,0 +1,68 @@
+
+Generating LaMEM model · GeophysicalModelGenerator.jl
In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.
In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:
As earthquakes are point-wise data, you have to specify this. Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where z is not pointing upwards).
In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
CartData
+ size : (1921, 1441, 1)
+ x ϵ [ -86.09445705828863 km : 73.67229892155609 km]
+ y ϵ [ -63.5531883197492 km : 73.28446155584604 km]
+ z ϵ [ -4.38297802734375 km : 2.414 km]
+ fields : (:Topography,)
+
It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:
In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command
Grid = ReadLaMEM_InputFile("LaPalma.dat")
LaMEM Grid:
+ nel : (64, 64, 32)
+ marker/cell : (3, 3, 3)
+ markers : (192, 192, 192)
+ x ϵ [-50.0 : 50.0]
+ y ϵ [-40.0 : 40.0]
+ z ϵ [-80.0 : 15.0]
+
The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.
In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.
Looking at the seismicity, there is a swarm at around 35 km depth
Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.
Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory
The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
Everything that fulfills this criteria gets the number 1, everything else 0.
Do the same with other tomographic models (using the same criteria or a different one).
Make sure that all tomographic models are interpolated to the same grid.
Sum up the 3 models.
The resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
So how do we create Votemaps? Doing this is rather simple:
This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:
And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
Write_Paraview(Data_VoteMap, "VoteMap_Alps")
In paraview, this gives
You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:
Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Example
julia> Lat = 1.0:3:10.0;
+julia> Lon = 11.0:4:20.0;
+julia> Depth = (-20:5:-10)*km;
+julia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);
+julia> Lon3D
+3×4×3 Array{Float64, 3}:
+[:, :, 1] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 2] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 3] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+julia> Lat3D
+ 3×4×3 Array{Float64, 3}:
+ [:, :, 1] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 2] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 3] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+julia> Depth3D
+ 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:
+ [:, :, 1] =
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+
+ [:, :, 2] =
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+
+ [:, :, 3] =
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+julia> Data = zeros(size(Lon3D));
+julia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))
+GeoData
+ size : (3, 4, 3)
+ lon ϵ [ 11.0 : 19.0]
+ lat ϵ [ 1.0 : 10.0]
+ depth ϵ [ -20.0 km : -10.0 km]
+ fields : (:DataFieldName,)
+ attributes: ["note"]
Data structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.
depth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Cartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
Data structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers
x,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
x,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.
Example
julia> x = 0:2:10
+julia> y = -5:5
+julia> z = -10:2:2
+julia> X,Y,Z = XYZGrid(x, y, z);
+julia> Data = Z
+julia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))
+CartData
+ size : (6, 11, 7)
+ x ϵ [ 0.0 km : 10.0 km]
+ y ϵ [ -5.0 km : 5.0 km]
+ z ϵ [ -10.0 km : 2.0 km]
+ fields : (:FakeData, :Data2)
+ attributes: ["note"]
CartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Read LaMEM processor partitioning file
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by ReadLaMEM_InputFile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.
Writes a structure with Geodatato a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), setPointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to passtimeandpvd`
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = Movie_Paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = Write_Paraview(Data, name, pvd=movie, time=itime)
+end
+Movie_Paraview(pvd=movie, Finalize=true)
Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).
If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).
Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.
As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.
Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):
Whereas this is now in UTM Data (in meters), it is distorted.
Often it is more convenient to have this in CartData, which is done in a similar manner:
julia> Topo_Cart = Convert2CartData(Topo,p)
+CartData
+ size : (165, 75, 1)
+ x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]
+ y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]
+ z ϵ [ -4.9855 km : 3.123 km]
+ fields : (:Topography,)
This shows that the model is ~5600 by 3000 km.
Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Creates a cross-section through a volumetric (3D) GeoData object.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Interpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
Below = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded.
The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area.
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
diff --git a/v0.4.7/man/tutorial_ISC_data/index.html b/v0.4.7/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..d5c074d1
--- /dev/null
+++ b/v0.4.7/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from
Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004
Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:
# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)
+# when using the data please cite as:
+# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004
+X COORD (UTM Zone 32N) Y COORD (UTM Zone 32N) TOP (m.a.s.l) THICKNESS (m) DENSITY (Kg/m3)
+286635 4898615 -24823.2533 70418.125 3305
+286635 4918615 -25443.48901 69410.01563 3305
+286635 4938615 -28025.24511 66402.49219 3305
+286635 4958615 -32278.13135 61663.48438 3305
+286635 4978615 -35885.5625 57459.14063 3305
+286635 4998615 -37270.9812 55318.71094 3305
+286635 5018615 -36134.30481 55497.16406 3305
+286635 5038615 -34866.0697 55555.41406 3305
So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:
The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).
julia> res = ( length(unique(ns)), length(unique(ew)), 1)
+julia> EW = reshape(ew,res)
+julia> NS = reshape(ns,res)
+julia> Depth = reshape(depth,res)
+julia> T = reshape(thick,res)
+julia> Rho = reshape(rho,res)
So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
diff --git a/v0.4.7/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.4.7/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..288f519c
--- /dev/null
+++ b/v0.4.7/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:
Two shape files containing coastline and faults:
Vilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508
Earthquake data for two volcanic unrests, in 1983-84 and 2005-2016:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
De Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817
Travel time tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Ambient noise tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Load both the the shape (.shp) files contained in "./Geomorphology/*.shp" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:
To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates
Now let's plot earthquake data provided as text files. Start loading the data contained in "./SeismicLocations/*.txt". The first column gives us a temporal marker we can use to plot earthquakes in different periods.
Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in "./TravelTmeTomography/modvPS.dat" for both cartesian and UTM coordinates.
Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files "./NoiseTomography/*.txt". We read them consecutively in a "for" loop:
julia> list_files = glob("AmbientNoiseTomography/*.txt");
+julia> li = size(list_files, 1);
+julia> for i = 1:li
+julia> nameFile = list_files[i];
+julia> name_vts = name_vts[24:26];
+julia> data = readdlm(nameFile, '\t', Float64);
+julia> WE = data[:,1];
+julia> SN = data[:,2];
+julia> depth = data[:,3];
+julia> Vs = data[:,4];
However these models are too wide, so it is better to constrain them:
julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );
+julia> WE = WE[ind];
+julia> SN = SN[ind];
+julia> depth = depth[ind];
+julia> Vs = Vs[ind];
Also, nodes are irregular, hence we create a 3D regular UTM:
This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:
Earthquake data for the 1983-84 unrest:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
You will need to download the zipped folder containing all files from here.
Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here
Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.
julia> using DelimitedFiles, GeophysicalModelGenerator, Dates
+julia> p2 = @__FILE__;
+julia> p2last = findlast("/",p2);
+julia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);
+julia> output_path = string(p3,"/");
+julia> movie = Movie_Paraview(name=string(p3,"/TemporalSeismicity"), Initialize=true);
+julia> if isdir(string(p3,"/TemporalSeismicity"))==0
+julia> mkdir(string(p3,"/TemporalSeismicity"));
+julia> end
+
Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.
julia> data = readdlm("SeismicLocations/Seismicity_UTM_1983_1984.txt", '\t', skipstart=0, header=false);
+julia> l = length(data[:,1]);
+julia> dates = Date.(zeros(l,1))
+julia> for i = 1:l
+julia> df = DateFormat("yyyymmdd");
+julia> t1 = string("19",@sprintf("%5.o", data[i,1]));
+julia> t2 = Date(t1[1:8],df);
+julia> dates[i,1] = t2;
+julia> end
+julia> WE = data[:,2];
+julia> SN = data[:,3];
+julia> depth = data[:,4];
+julia> dates_num = dates - dates[1];
+
Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.
julia> nt = 50;
+julia> dt = Dates.Day(nt);
+julia> t = minimum(dates):dt:maximum(dates);
+julia> for itime = 1:length(t)-1
+julia> name = string(p3,"/TemporalSeismicity/", string(itime));
+julia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);
+julia> we = WE[tt];
+julia> sn = SN[tt];
+julia> Depth1 = depth[tt];
+julia> DN = dates_num[tt];
+julia> label_time = Dates.value(DN[end]);
+julia> if size(tt,1)>1
+julia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));
+julia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);
+julia> end
+julia>end
+julia>Movie_Paraview(pvd=movie, Finalize=true)
+
This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.
Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.
It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:
julia> using GeophysicalModelGenerator, GLMakie
+julia> using GMT, JLD2
The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).
julia> ;
+shell> cd ~/Downloads/Zhao_etal_2016_data/
Now you can use the backspace key to return to the REPL, where we will load the data
julia> Data = JLD2.load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp");
At this stage you can look at it with
julia> Visualise(Data);
Note that this tends to take a while, the first time you do this (faster afterwards).
Let's add topography to the plot as well, which requires us to first load that:
This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.
And once we have done that, you can visualize the data in the same way:
julia> Visualise(Data_Cart, Topography=Topo_Cart)
Missing docstring.
Missing docstring for GeophysicalModelGenerator.Visualise. Check Documenter's build log for details.
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
diff --git a/v0.4.7/scripts/LaPalma.dat b/v0.4.7/scripts/LaPalma.dat
new file mode 100644
index 00000000..f64edccf
--- /dev/null
+++ b/v0.4.7/scripts/LaPalma.dat
@@ -0,0 +1,361 @@
+# Define number of elements in x, y, z-direction
+# Negative number implies corresponding number of mesh segments
+# Data is provided in the variables seg_x, seg_y, seg_z and includes:
+# * coordinates of the delimiters between the segments (n-1 points)
+# * number of cells (n points)
+# * bias coefficients (n points)
+
+
+#===============================================================================
+# Scaling
+#===============================================================================
+
+# Geometry
+units = geo
+
+# Always in SI units!!
+unit_temperature = 500
+unit_length = 1000
+unit_viscosity = 1e19
+unit_stress = 1e9
+
+#===============================================================================
+# Time stepping parameters
+#===============================================================================
+
+ dt = 5e-4 # time step
+ dt_min = 4.5e-4 # minimum time step (declare divergence if lower value is attempted)
+ dt_max = 1e-3 # maximum time step
+ inc_dt = 1 # time step increment per time step (fraction of unit)
+ CFL = 0.5 # CFL (Courant-Friedrichs-Lewy) criterion
+ CFLMAX = 0.8 # CFL criterion for elasticity
+ nstep_ini = 0 # save output for n initial steps
+ nstep_max = 20 # maximum allowed number of steps (lower bound: time_end/dt_max)
+ nstep_out = 1 # save output every n steps
+
+#===============================================================================
+# Grid & discretization parameters
+#===============================================================================
+
+# relative geometry tolerance for grid manipulations (default 1e-9)
+
+ gtol = 1e-9
+
+# Number of cells for all segments
+ nel_x = 64
+ nel_y = 64
+ nel_z = 32
+
+# Coordinates of all segments (including start and end points)
+ coord_x = -50 50
+ coord_y = -40 40
+ coord_z = -80 15
+
+#===============================================================================
+# Free surface
+#===============================================================================
+
+ surf_use = 1 # free surface activation flag
+ surf_corr_phase = 1 # air phase ratio correction flag (due to surface position)
+ surf_level = 5 # initial level
+ surf_air_phase = 0 # phase ID of sticky air layer
+ surf_max_angle = 45.0 # maximum angle with horizon (smoothed if larger)
+ surf_topo_file = LaPalma_Topo.topo # initial topography file (redundant)
+ erosion_model = 0 # erosion model [0-none (default), 1-infinitely fast]
+ sediment_model = 0 # sedimentation model [0-none (dafault), 1-prescribed rate]
+
+#===============================================================================
+# Boundary conditions
+#===============================================================================
+
+# noslip = 0 0 0 0 0 0
+
+ temp_top = 0 # Temperature @ top
+ temp_bot = 1350 # Temperature @ bottom; side BC's are flux-free
+
+ # Background strain rate parameters
+# exx_num_periods = 1 # number intervals of constant strain rate (x-axis)
+# exx_strain_rates = -5e-16 # strain rates for each interval (negative=compression)
+
+ # Free surface top boundary flag
+ open_top_bound = 1
+
+#===============================================================================
+# Jacobian & residual evaluation parameters
+#===============================================================================
+
+ gravity = 0.0 0.0 -9.81 # gravity vector
+ act_temp_diff = 1 # temperature diffusion activation flag
+ #act_steady_temp = 0 # steady-state temperature initial guess activation flag
+ #steady_temp_t = 0.1 # time for (quasi-)steady-state temperature initial guess
+ #nstep_steady = 50 # number of steps for (quasi-)steady-state temperature initial guess (default = 1)
+ act_heat_rech = 0 # heat recharge activation flag
+ init_lith_pres = 1 # initial pressure with lithostatic pressure
+ init_guess = 1 # initial guess flag
+ eta_min = 1e18 # viscosity upper bound
+ eta_max = 1e23 # viscosity lower limit
+ eta_ref = 1e19 # reference viscosity (initial guess)
+ T_ref = 20 # reference temperature
+
+#===============================================================================
+# Solver options
+#===============================================================================
+
+ SolverType = multigrid # solver [direct or multigrid]
+ MGLevels = 4 # number of MG levels [default=3]
+
+#===============================================================================
+# Model setup & advection
+#===============================================================================
+
+ msetup = files
+ mark_load_file = ./markers/mdb # marker input file (extension is .xxxxxxxx.dat)
+
+ #poly_file = ../Polygons/RoundTopShort_256_128_21_09_20.bin
+ nmark_x = 3 # markers per cell in x-direction
+ nmark_y = 3 # ... y-direction
+ nmark_z = 3 # ... z-direction
+# rand_noise = 1 # random noise flag
+ advect = rk2 # advection scheme
+ interp = minmod # velocity interpolation scheme
+# stagp_a = 0.7 # STAG_P velocity interpolation parameter
+ mark_ctrl = basic # marker control type
+ nmark_lim = 16 100 # min/max number per cell
+
+#===============================================================================
+# Output
+#===============================================================================
+
+# Grid output options (output is always active)
+ out_file_name = LaPalma_test # output file name
+ out_pvd = 1 # activate writing .pvd file
+ out_phase = 1
+ out_density = 1
+ out_visc_total = 1
+ out_visc_creep = 1
+ out_visc_plast = 1
+ out_velocity = 1
+ out_pressure = 1
+ out_over_press = 1
+ out_litho_press = 1
+ out_temperature = 1
+# out_dev_stress = 1
+ out_j2_dev_stress = 1
+# out_strain_rate = 1
+ out_j2_strain_rate = 1
+ out_plast_strain = 1
+ out_plast_dissip = 1
+ out_tot_displ = 1
+ out_moment_res = 1
+ out_cont_res = 1
+ out_yield = 1
+
+# AVD phase viewer output options (requires activation)
+ out_avd = 1 # activate AVD phase output
+ out_avd_pvd = 1 # activate writing .pvd file
+ out_avd_ref = 1 # AVD grid refinement factor
+
+# free surface output
+ out_surf = 1 # activate surface output
+ out_surf_pvd = 1 # activate writing .pvd file
+ out_surf_velocity = 1
+ out_surf_topography = 1
+ out_surf_amplitude = 1
+
+
+#===============================================================================
+# ............................ Material Parameters .............................
+#===============================================================================
+
+# ------------------- Air -------------------
+
+ Name = air
+ ID = 0
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Water -------------------
+
+ Name = water
+ ID = 1
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+# ------------------- Upper Crust -------------------
+
+ Name = Crust
+ ID = 2
+ rho = 2900
+ alpha = 3e-5
+
+ # dislocation viscosity
+ #disl_prof = Plagioclase_An75-Ranalli_1995
+ #disl_prof = Wet_Quarzite-Ranalli_1995
+ disl_prof = Mafic_Granulite-Ranalli_1995
+
+
+ # Elastic parameters
+ G = 3e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+
+# ------------------- Mantle lithosphere-------------------
+
+ Name = Mantle
+ ID = 3
+ rho = 3320
+ alpha = 3e-5
+
+ # dislocation viscosity
+ disl_prof = Dry_Olivine-Ranalli_1995
+
+ # Elastic parameters
+ G = 6.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3.3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Andesite -------------------
+
+ Name = magma
+ ID = 4
+ rho = 2700
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e18
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 980
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Dacite -------------------
+
+ ID = 5
+ rho = 2575
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e19
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 800
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+# End of defining material properties for all phases ----------------------------------------
+
+
+#===============================================================================
+# PETSc options
+#===============================================================================
+
+
+# SNES
+
+ -snes_npicard 5
+ -snes_max_it 200
+ -snes_rtol 1e-6
+ -snes_atol 1e-6
+ -snes_PicardSwitchToNewton_rtol 1e-7 #-7
+ #-snes_NewtonSwitchToPicard_it 1 # number of Newton iterations after which we switch back to Picard
+# -snes_monitor
+# -snes_linesearch_monitor
+
+# Jacobian solver
+ -js_ksp_type fgmres
+ -js_ksp_monitor
+ -js_ksp_max_it 30
+ -js_ksp_rtol 1e-5
+ -js_ksp_atol 1e-6
+# -js_ksp_monitor_true_residual
+
+# -its_ksp_monitor
+# -ts_ksp_monitor
+
+# Multigrid
+ -gmg_pc_mg_galerkin
+ -gmg_pc_mg_type multiplicative
+ -gmg_pc_mg_cycle_type v
+
+ -gmg_mg_levels_ksp_type richardson
+ -gmg_mg_levels_ksp_richardson_scale 0.5
+ -gmg_mg_levels_ksp_max_it 5
+ -gmg_mg_levels_pc_type jacobi
+
+ -crs_pc_factor_mat_solver_package pastix
+
+
+
+
+
+
+
diff --git a/v0.4.7/scripts/LaPalma_example.jl b/v0.4.7/scripts/LaPalma_example.jl
new file mode 100644
index 00000000..e1575367
--- /dev/null
+++ b/v0.4.7/scripts/LaPalma_example.jl
@@ -0,0 +1,125 @@
+# # Create a 3D LaMEM setup for La Palma
+#
+# ## Aim
+# In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021.
+# LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from `GeoData` to `CartData`.
+#
+#
+# ## 1. Load data
+# We will use two types of data to create the model
+# 1) Topography
+# 2) Earthquake locations
+
+# We start with loading the required packages
+using GeophysicalModelGenerator, JLD2
+using GMT
+
+# In case you managed to install GMT on your machine, you can automatically download the topography with
+Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file="@earth_relief_03s.grd")
+
+# In case you did not manage that, we have prepared a JLD2 file [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1).
+# Download it, and doublecheck that you are in the same directory as the data file with:
+pwd()
+
+# Load the data:
+Topo=load("Topo_LaPalma.jld2","Topo")
+
+# Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from [https://www.ign.es/web/ign/portal/vlc-catalogo](https://www.ign.es/web/ign/portal/vlc-catalogo)).
+# Download that [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1)
+data_all_EQ = load("EQ_Data.jld2","data_all_EQ")
+
+# Write the data to paraview with
+Write_Paraview(data_all_EQ,"data_all_EQ",PointsData=true)
+Write_Paraview(Topo,"Topo")
+
+# As earthquakes are point-wise data, you have to specify this.
+# ![LaPalma_EQTopo_GeoData](../assets/img/TopoEQs_LaPalma_GeoData.png)
+# Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where `z` is *not* pointing upwards).
+
+# ## 2. Convert data
+# In order to create model setups, it is helpful to first transfer the data to Cartesian.
+# This requires us to first determine a *projection point*, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
+proj = ProjectionPoint(Lon=-17.84, Lat=28.56)
+
+# Once this is done you can convert the topographic data to the cartesian reference frame
+EQ_cart = Convert2CartData(data_all_EQ, proj);
+Topo_cart = Convert2CartData(Topo, proj)
+
+# It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small.
+# In other cases, however, this is quite substantial (e.g., India-Asia collision zone).
+# LaMEM needs an orthogonal grid of topography, which we can create with:
+Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));
+
+# In a next step, the routine `ProjectCartData` projects a `GeoData` structure to a `CartData` struct
+Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)
+
+# Let's have a look at the data:
+Write_Paraview(EQ_cart,"EQ_cart",PointsData=true)
+Write_Paraview(Topo_LaMEM,"Topo_LaMEM")
+
+# ## 3. Create LaMEM setup
+#
+# In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and
+# the number of control volumes (elements), you want to apply in every direction.
+# The LaMEM input file can be downloaded [here](../scripts/LaPalma.dat).
+# Make sure you are in the same directory as the *.dat file & execute the following command
+Grid = ReadLaMEM_InputFile("LaPalma.dat")
+
+# The `LaMEM_grid` structure contains the number of elements in every direction and the number of markers in every cell.
+# It also contains `Grid.X`, `Grid.Y`, `Grid.Z`, which are the coordinates of each of the markers in the 3 directions.
+#
+# In a next step we need to give each of these points a `Phase` number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
+Phases = ones(Int32,size(Grid.X))*2;
+Temp = ones(Float64,size(Grid.X));
+
+# In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers
+Geotherm = 30;
+Temp = -Grid.Z.*Geotherm;
+
+# Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)
+Temp[Temp.<20] .= 20;
+Temp[Temp.>1350] .= 1350;
+
+# Because of lacking data, we have pretty much no idea where the Moho is in La Palma.
+# Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
+ind = findall( Grid.Z .< -40);
+Phases[ind] .= 3;
+
+# Everything above the free surface is assumed to be "air"
+ind = AboveSurface(Grid, Topo_cart);
+Phases[ind] .= 0;
+
+# And all "air" points that are below sea-level becomes "water"
+ind = findall( (Phases.==0) .& (Grid.Z .< 0));
+Phases[ind] .= 1;
+
+# You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small).
+# If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses.
+# We will assume the second option in our model setup.
+#
+# Looking at the seismicity, there is a swarm at around 35 km depth
+AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# A shallower one exists as well
+AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# And there might be a mid-crustal one
+AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# We can generate a 3D model setup, which must include the `Phases` and `Temp` arrays
+Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))
+Write_Paraview(Model3D,"Model3D")
+
+# The model setup looks like this
+# ![LaMEM_ModelSetup_LaPalma](../assets/img/LaMEM_ModelSetup_LaPalma.png)
+
+# We can create a LaMEM marker file from the `Model3D` setup and the (cartesian) topography
+Save_LaMEMTopography(Topo_cart, "Topography.txt")
+Save_LaMEMMarkersParallel(Model3D)
+
+# Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well.
+# If you are interested in doing this, have a look at the LaMEM [wiki](https://bitbucket.org/bkaus/lamem/wiki/Home) pages.
+
+
+#src Note: The markdown page is generated using:
+#src Literate.markdown("LaPalma_example.jl",outputdir="../man/", execute=true)
\ No newline at end of file
diff --git a/v0.4.7/scripts/Tutorial_Votemaps.jl b/v0.4.7/scripts/Tutorial_Votemaps.jl
new file mode 100644
index 00000000..597f26cc
--- /dev/null
+++ b/v0.4.7/scripts/Tutorial_Votemaps.jl
@@ -0,0 +1,77 @@
+# # Votemaps
+#
+# ## Aim
+# In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.
+#
+# ## Steps
+#
+# #### 1. Load data
+# We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to
+# [https://seafile.rlp.net/d/22b0fb85550240758552/](https://seafile.rlp.net/d/22b0fb85550240758552/)
+#
+# Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form
+# Download the corresponding *.jld2 files to the same directory
+using JLD2, GeophysicalModelGenerator
+
+Pwave_Zhao = load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp")
+PSwave_Koulakov = load("Koulakov_Europe.jld2","DataKoulakov_Alps")
+Pwave_Paffrath = load("Paffrath_Pwave.jld2","Data_set_Paffrath2021_Vp")
+
+# The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
+Pwave_Paffrath
+GeoData
+ size : (162, 130, 42)
+ lon ϵ [ -13.3019 : 35.3019]
+ lat ϵ [ 30.7638 : 61.2362]
+ depth ϵ [ -606.0385 km : 31.0385 km]
+ fields: (:dVp_Percentage, :Vp, :Resolution)
+
+PSwave_Koulakov
+ GeoData
+ size : (108, 81, 35)
+ lon ϵ [ 4.0 : 20.049999999999997]
+ lat ϵ [ 37.035928143712574 : 49.01197604790419]
+ depth ϵ [ -700.0 km : -10.0 km]
+ fields: (:dVp_percentage, :dVs_percentage)
+
+# #### 2. Creating a Votemap
+# The idea of `Votemaps` is rather simple:
+# - assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
+# - Everything that fulfills this criteria gets the number 1, everything else 0.
+# - Do the same with other tomographic models (using the same criteria or a different one).
+# - Make sure that all tomographic models are interpolated to the same grid.
+# - Sum up the 3 models.
+# - The resulting 3D map will have the number `3` at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
+#
+# The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
+#
+# So how do we create Votemaps?
+# Doing this is rather simple:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_percentage>2.0","dVp_Percentage>2.0"], dims=(100,100,100))
+
+# This will look at the common `lon`,`lat`,`depth` ranges between all 3 models, interpret each of the models to a common grid of size `(100,100,100)` and apply each of the criteria specified
+# The resulting `GeoData` struct looks like:
+GeoData
+ size : (100, 100, 100)
+ lon ϵ [ 4.0 : 18.0]
+ lat ϵ [ 38.0 : 49.01197604790419]
+ depth ϵ [ -606.0385 km : -10.0 km]
+ fields: (:VoteMap,)
+
+# And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
+Write_Paraview(Data_VoteMap, "VoteMap_Alps")
+
+# In paraview, this gives
+# ![Tutorial_VoteMap](../assets/img/Tutorial_VoteMap.png)
+
+# You can ofcourse argue that newer tomographic models include more data & should therefore count more
+# A simple way to take that into account is to list the model twice:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_Percentage>3.0", "dVp_percentage>2.0","dVp_Percentage>2.0"],
+ dims=(100,100,100))
+
+# Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
+
+
+
diff --git a/v0.4.7/search/index.html b/v0.4.7/search/index.html
new file mode 100644
index 00000000..2263a7df
--- /dev/null
+++ b/v0.4.7/search/index.html
@@ -0,0 +1,2 @@
+
+Search · GeophysicalModelGenerator.jl
Loading search...
Settings
This document was generated with Documenter.jl on Friday 16 December 2022. Using Julia version 1.7.3.
diff --git a/v0.4.7/search_index.js b/v0.4.7/search_index.js
new file mode 100644
index 00000000..7ec9a78d
--- /dev/null
+++ b/v0.4.7/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData\nGeophysicalModelGenerator.Screenshot_To_UTMData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_UTMData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_UTMData","text":"Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true)\n\nDoes the same as Screenshot_To_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tutorial_local_Flegrei/#Km-scale-volcano-tutorial-using-cartesian-coordinates","page":"Kilometer-scale volcano","title":"Km-scale volcano tutorial using cartesian coordinates","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#Goal","page":"Kilometer-scale volcano","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Two shape files containing coastline and faults:\nVilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508\nEarthquake data for two volcanic unrests, in 1983-84 and 2005-2016:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7\nDe Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817\nTravel time tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x\nAmbient noise tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x","category":"page"},{"location":"man/tutorial_local_Flegrei/#Steps","page":"Kilometer-scale volcano","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#.-Download-all-data-for-region","page":"Kilometer-scale volcano","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Make sure that you are in the unzipped directory.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Geomorphology","page":"Kilometer-scale volcano","title":"2. Geomorphology","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Load both the the shape (.shp) files contained in \"./Geomorphology/*.shp\" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Geomorphology)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Earthquakes","page":"Kilometer-scale volcano","title":"3. Earthquakes","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Now let's plot earthquake data provided as text files. Start loading the data contained in \"./SeismicLocations/*.txt\". The first column gives us a temporal marker we can use to plot earthquakes in different periods.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Glob, GeoStats\njulia> data_80s = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> data_00s = readdlm(\"SeismicLocations/Seismicity_UTM_2005_2016.txt\", ' ', skipstart=0, header=false);\njulia> data = vcat(data_80s,data_00s) \njulia> time = data[:,1];\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> EQ_Data_Cart = CartData(WE,SN,depth,(Depth=depth * m,Time=time * yr,));\njulia> Write_Paraview(EQ_Data_Cart, \"CF_Earthquakes_Cartesian\", PointsData=true)\njulia> EQ_Data_UTM = UTMData(WE, SN, depth, 33, true, (Depth=depth * m,Time=time * yr,));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,EQ_Data_UTM)\njulia> Write_Paraview(Data_set_UTM, \"CF_Earthquakes_UTM\", PointsData=true)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Save in paraview with both cartesian and UTM formats. The final seismicity map looks like this:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_seismicity)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"The colour scale distinguishes earthquakes of different decades. Notice the progressive migration of recent seismicity (black dots) towards East.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Velocity-model","page":"Kilometer-scale volcano","title":"4. Velocity model","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in \"./TravelTmeTomography/modvPS.dat\" for both cartesian and UTM coordinates.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"TravelTimeTomography/modvPS.dat\", '\\t', Float64, skipstart=0, header=false);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vp = data[:,4];\njulia> Vs = data[:,5];\njulia> VpVs = data[:,6];\njulia> resolution = (length(unique(depth)), length(unique(SN)), length(unique(WE)))\njulia> dim_perm = [3 2 1]\njulia> we = permutedims(reshape(WE, resolution), dim_perm);\njulia> sn = permutedims(reshape(SN, resolution), dim_perm);\njulia> depth = permutedims(reshape(depth, resolution), dim_perm);\njulia> Vp3d = permutedims(reshape(Vp, resolution), dim_perm);\njulia> Vs3d = permutedims(reshape(Vs, resolution), dim_perm);\njulia> Vp_Vs3d = permutedims(reshape(VpVs, resolution), dim_perm);\njulia> Data_set_Cartesian = CartData(we, sn, depth, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Write_Paraview(Data_set_Cartesian, \"CF_Velocity_Cartesian\")\njulia> Data_set = UTMData(we, sn, depth, 33, true, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,Data_set)\njulia> Write_Paraview(Data_set_UTM, \"CF_Velocity_UTM\")","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Including the Vp/Vs model in the previous Paraview file workspace:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_VpVs)","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Horizontal-slices-of-shear-velocity-on-irregular-grid","page":"Kilometer-scale volcano","title":"5. Horizontal slices of shear velocity on irregular grid","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files \"./NoiseTomography/*.txt\". We read them consecutively in a \"for\" loop:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> list_files = glob(\"AmbientNoiseTomography/*.txt\");\njulia> li = size(list_files, 1);\njulia> for i = 1:li\njulia> nameFile = list_files[i];\njulia> name_vts = name_vts[24:26];\njulia> data = readdlm(nameFile, '\\t', Float64);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"However these models are too wide, so it is better to constrain them:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );\njulia> WE = WE[ind];\njulia> SN = SN[ind];\njulia> depth = depth[ind];\njulia> Vs = Vs[ind];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Also, nodes are irregular, hence we create a 3D regular UTM:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> l = length(WE);\njulia> n_WE = minimum(WE):100:maximum(WE);\njulia> n_SN = minimum(SN):100:maximum(SN);\njulia> we, sn, Depth = XYZGrid(n_WE, n_SN, depth[1]);\njulia> Vs_3D = zeros(size(Depth));\njulia> Cgrid = GeoStats.CartesianGrid((size(we, 1), size(we, 2)), (minimum(we), minimum(sn)), (we[2,2,1] - we[1,1,1], sn[2,2,1] - sn[1,1,1]))\njulia> coord = PointSet([WE[:]'; SN[:]']);\njulia> Geo = georef((Vs = Vs[:],), coord);\njulia> P = EstimationProblem(Geo, Cgrid, :Vs);\njulia> S = IDW(:Vs => (;neighbors=2));\njulia> sol = solve(P, S);\njulia> sol_Vs = values(sol).Vs;\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)));\njulia> Vs_3D[:,:,1] = Vs_2D;\njulia> Data_set_Cart = CartData(we, sn, Depth, (Vs = Vs_3D * (km / s),))\njulia> Write_Paraview(Data_set_Cart, \"CF_Noise\" * name_vts * \"_Cartesian\")\njulia> Data_set = UTMData(we, sn, Depth, 33, true, (Vs = Vs_3D*(km / s),));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData, Data_set);\njulia> Write_Paraview(Data_set_UTM, \"CF_Noise_UTM_\"*name_vts)\njulia> end","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This is one of the horizontal sections created by the code in the previous model in both reference systems:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Noise)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!\nGeophysicalModelGenerator.Convert2UTMzone\nGeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ImportTopo\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.DrapeOnTopo\nGeophysicalModelGenerator.LithostaticPressure!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(Volume::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a volumetric (3D) GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nInterpolate indicates whether we want to simply extract the data from the 3D volume (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData \n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::GeoData, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\n\n\n\n\nInterpolateDataFields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values. \n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData \n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Grid::CartGrid, DataSurface_Cart::CartData; above=true)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf. nex\n\nExample\n\njulia> Data\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n ParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.DrapeOnTopo","page":"Tools","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"Topo = DrapeOnTopo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo \n\n\n\n\n\nDrapeOnTopo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography \n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.LithostaticPressure!","page":"Tools","title":"GeophysicalModelGenerator.LithostaticPressure!","text":"LithostaticPressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max], grid=true);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Julia-script","page":"3D seismic tomography from ASCII","title":"Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.UTMData\nGeophysicalModelGenerator.ParaviewData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid\nGeophysicalModelGenerator.XYZGrid\nGeophysicalModelGenerator.ProjectionPoint","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> Lat = 1.0:3:10.0;\njulia> Lon = 11.0:4:20.0;\njulia> Depth = (-20:5:-10)*km;\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);\njulia> Lon3D\n3×4×3 Array{Float64, 3}:\n[:, :, 1] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 2] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 3] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\njulia> Lat3D\n 3×4×3 Array{Float64, 3}:\n [:, :, 1] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 2] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 3] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\njulia> Depth3D\n 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:\n [:, :, 1] =\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n \n [:, :, 2] =\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n \n [:, :, 3] =\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\njulia> Data = zeros(size(Lon3D));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,)) \nGeoData \n size : (3, 4, 3)\n lon ϵ [ 11.0 : 19.0]\n lat ϵ [ 1.0 : 10.0]\n depth ϵ [ -20.0 km : -10.0 km]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.UTMData","page":"Data Structures","title":"GeophysicalModelGenerator.UTMData","text":"UTMData(EW::Any, NS:Any, depth::GeoUnit, UTMZone::Int, NorthernHemisphere=true, fields::NamedTuple)\n\nData structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.\n\ndepth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> ew = 422123.0:100:433623.0\njulia> ns = 4.514137e6:100:4.523637e6\njulia> depth = -5400:250:600\njulia> EW,NS,Depth = XYZGrid(ew, ns, depth);\njulia> Data = ustrip.(Depth);\njulia> Data_set = UTMData(EW,NS,Depth,33, true, (FakeData=Data,Data2=Data.+1.)) \nUTMData \n UTM zone : 33-33 North\n size : (116, 96, 25)\n EW ϵ [ 422123.0 : 433623.0]\n NS ϵ [ 4.514137e6 : 4.523637e6]\n depth ϵ [ -5400.0 m : 600.0 m]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nIf you wish, you can convert this from UTMData to GeoData with\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nwhich would allow visualizing this in paraview in the usual manner:\n\njulia> Write_Paraview(Data_set1, \"Data_set1\")\n1-element Vector{String}:\n \"Data_set1.vts\"\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.ParaviewData","page":"Data Structures","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(ParaviewData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::Any, y::Any, z::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers\n\nx,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nx,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData \n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nCartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with\n\njulia> Write_Paraview(Data_set, \"Data_set\")\n1-element Vector{String}:\n \"Data_set.vts\"\n\nIf you wish, you can convert this to UTMData (which will simply convert the )\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields: (:FakeData, :Data2)\n\nwhich would allow visualizing this in paraview in the usual manner:\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.ProjectionPoint","page":"Data Structures","title":"GeophysicalModelGenerator.ProjectionPoint","text":"struct ProjectionPoint\n Lon :: Float64\n Lat :: Float64\n EW :: Float64\n NS :: Float64\n zone :: Integer\n isnorth :: Bool\nend\n\nStructure that holds the coordinates of a point that is used to project a data set from Lon/Lat to a Cartesian grid and vice-versa.\n\n\n\n\n\n","category":"type"},{"location":"man/tutorial_time_Seismicity/#How-to-create-a-movie-to-show-seismic-distribution-through-time","page":"Create movies","title":"How to create a movie to show seismic distribution through time","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#Goal","page":"Create movies","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Earthquake data for the 1983-84 unrest:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7","category":"page"},{"location":"man/tutorial_time_Seismicity/#Steps","page":"Create movies","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#.-Download-all-data-for-region","page":"Create movies","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_1)","category":"page"},{"location":"man/tutorial_time_Seismicity/#.-Earthquakes-in-movie","page":"Create movies","title":"2. Earthquakes in movie","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Dates\njulia> p2 = @__FILE__;\njulia> p2last = findlast(\"/\",p2);\njulia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);\njulia> output_path = string(p3,\"/\");\njulia> movie = Movie_Paraview(name=string(p3,\"/TemporalSeismicity\"), Initialize=true);\njulia> if isdir(string(p3,\"/TemporalSeismicity\"))==0\njulia> mkdir(string(p3,\"/TemporalSeismicity\"));\njulia> end\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> data = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> l = length(data[:,1]);\njulia> dates = Date.(zeros(l,1))\njulia> for i = 1:l\njulia> df = DateFormat(\"yyyymmdd\");\njulia> t1 = string(\"19\",@sprintf(\"%5.o\", data[i,1]));\njulia> t2 = Date(t1[1:8],df);\njulia> dates[i,1] = t2;\njulia> end\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> dates_num = dates - dates[1];\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> nt = 50;\njulia> dt = Dates.Day(nt);\njulia> t = minimum(dates):dt:maximum(dates);\njulia> for itime = 1:length(t)-1\njulia> name = string(p3,\"/TemporalSeismicity/\", string(itime));\njulia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);\njulia> we = WE[tt];\njulia> sn = SN[tt];\njulia> Depth1 = depth[tt];\njulia> DN = dates_num[tt];\njulia> label_time = Dates.value(DN[end]);\njulia> if size(tt,1)>1\njulia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));\njulia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);\njulia> end\njulia>end\njulia>Movie_Paraview(pvd=movie, Finalize=true)\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_PVD)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_Movie)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section & create VTS file\n3. Read data of a mapview & create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 4.65, 45.73, -400.0)\njulia> Corner_UpperRight = (17.23, 43.80, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = (4.65 , 45.73 , -400.0 )\n └ lower right = (17.23 , 43.8 , -400.0 )\n └ upper left = (4.65 , 45.73 , 0.0 )\n └ upper right = (17.23 , 43.8 , 0.0 )\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 4.6499999999999995 : 17.230000000000004]\n lat ϵ [ 43.79999999999999 : 45.730000000000004]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/visualise/#Visualisation","page":"Visualisation","title":"Visualisation","text":"","category":"section"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> using GeophysicalModelGenerator, GLMakie\njulia> using GMT, JLD2","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> ;\nshell> cd ~/Downloads/Zhao_etal_2016_data/ ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Now you can use the backspace key to return to the REPL, where we will load the data","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Data = JLD2.load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\"); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"At this stage you can look at it with","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Note that this tends to take a while, the first time you do this (faster afterwards).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Let's add topography to the plot as well, which requires us to first load that:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Topo = ImportTopo([0,18,38,52], file=\"@earth_relief_01m.grd\");\njulia> Visualise(Data, Topography=Topo); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Which will look like: (Image: Tutorial_Visualize)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> p=ProjectionPoint(Lon=10, Lat=45)\nProjectionPoint(45.0, 10.0, 578815.302916711, 4.983436768349297e6, 32, true)\njulia> Data_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,-1000:10:-1));\njulia> Topo_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,0));\njulia> Topo_Cart = ProjectCartData(Topo_Cart, Topo, p)\nCartData \n size : (121, 121, 1)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -3.6270262031545473 : 3.654942280296281]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Data_Cart = ProjectCartData(Data_Cart, Data, p)\nCartData \n size : (121, 121, 100)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -1000.0 : -10.0]\n fields : (:dVp_Percentage,)\n attributes: [\"note\"]","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"And once we have done that, you can visualize the data in the same way:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data_Cart, Topography=Topo_Cart)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"GeophysicalModelGenerator.Visualise","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview\nGeophysicalModelGenerator.Movie_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"pvd = Write_Paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a structure with Geodatato a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), setPointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to passtimeandpvd`\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\nWrite_Paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\nWrite_Paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"function"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Movie_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Movie_Paraview","text":"pvd = Movie_Paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = Movie_Paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = Write_Paraview(Data, name, pvd=movie, time=itime)\nend\nMovie_Paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"function"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"EditURL = \"/Tutorial_Votemaps.jl\"","category":"page"},{"location":"man/Tutorial_Votemaps/#Votemaps","page":"VoteMaps","title":"Votemaps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#Aim","page":"VoteMaps","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.","category":"page"},{"location":"man/Tutorial_Votemaps/#Steps","page":"VoteMaps","title":"Steps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#.-Load-data","page":"VoteMaps","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to https://seafile.rlp.net/d/22b0fb85550240758552/","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"using JLD2, GeophysicalModelGenerator\n\nPwave_Zhao = load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\")\nPSwave_Koulakov = load(\"Koulakov_Europe.jld2\",\"DataKoulakov_Alps\")\nPwave_Paffrath = load(\"Paffrath_Pwave.jld2\",\"Data_set_Paffrath2021_Vp\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Pwave_Paffrath\nGeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 km : 31.0385 km]\n fields: (:dVp_Percentage, :Vp, :Resolution)\n\nPSwave_Koulakov\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)","category":"page"},{"location":"man/Tutorial_Votemaps/#.-Creating-a-Votemap","page":"VoteMaps","title":"2. Creating a Votemap","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The idea of Votemaps is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)\nEverything that fulfills this criteria gets the number 1, everything else 0.\nDo the same with other tomographic models (using the same criteria or a different one).\nMake sure that all tomographic models are interpolated to the same grid.\nSum up the 3 models.\nThe resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"So how do we create Votemaps? Doing this is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"], dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"GeoData\n size : (100, 100, 100)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -606.0385 km : -10.0 km]\n fields: (:VoteMap,)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Write_Paraview(Data_VoteMap, \"VoteMap_Alps\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In paraview, this gives (Image: Tutorial_VoteMap)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_Percentage>3.0\", \"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"],\n dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/projection/#Projecting-and-converting-data","page":"Projection","title":"Projecting & converting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid). ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.","category":"page"},{"location":"man/projection/#.-Converting","page":"Projection","title":"1. Converting","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Converting from one coordinate system to the other is straightforward. Let's use Europe as an example:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo(lon = [-10, 45], lat=[25, 50], file=\"@earth_relief_20m\")\nGeoData \n size : (165, 75, 1)\n lon ϵ [ -10.0 : 44.666666666666664]\n lat ϵ [ 25.0 : 49.666666666666664]\n depth ϵ [ -4.9855 km : 3.123 km]\n fields: (:Topography,)\njulia> Write_Paraview(Topo,\"Topo\")\nSaved file: Topo.vts","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"The result is shown on the globe as: (Image: Topo_Europe_GeoData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can convert this to UTM zone as:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert(UTMData, Topo)\nUTMData \n UTM zone : 29-38 North\n size : (165, 75, 1)\n EW ϵ [ 197181.31221507967 : 769155.4572884373]\n NS ϵ [ 2.7649477474783654e6 : 5.505892073781423e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> p=ProjectionPoint(Lon=17.3, Lat=37.5)\nProjectionPoint(37.5, 17.3, 703311.4380385976, 4.152826288024972e6, 33, true)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Projecting the GeoData set using this projection point is done with:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Convert2UTMzone(Topo,p)\nUTMData \n UTM zone : 33-33 North\n size : (165, 75, 1)\n EW ϵ [ -2.0750691599137965e6 : 3.581351293385453e6]\n NS ϵ [ 2.7649477474783654e6 : 5.938114212160672e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is now in UTM Data (in meters), it is distorted. (Image: Topo_Europe_UTMData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Often it is more convenient to have this in CartData, which is done in a similar manner:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart = Convert2CartData(Topo,p)\nCartData \n size : (165, 75, 1)\n x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]\n y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]\n z ϵ [ -4.9855 km : 3.123 km]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"This shows that the model is ~5600 by 3000 km. (Image: Topo_Europe_CartData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal. ","category":"page"},{"location":"man/projection/#.-Projecting-data","page":"Projection","title":"2. Projecting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"For use with LaMEM, you would need an orthogonal cartesian grid. From the last command above we get some idea on the area, so we can create this:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = CartData(XYZGrid(-2000:20:2000,-1000:20:1000,0))\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Next, we can project the topographic data (in GeoData format) on this orthogonal grid","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = ProjectCartData(Topo_Cart_orth, Topo, p)\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ -4.485650671162607 km : 2.5909655318121865 km]\n fields : (:Topography,)\njulia> Write_Paraview(Topo_Cart_orth,\"Topo_Cart_orth\"); ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"(Image: Topo_Europe_CartData_Proj) So this interpolates the topographic data from the GeoData to the orthogonal cartesian grid (which can be used with LaMEM, for example).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can do similar projections with full 3D data sets or pointwise data. ","category":"page"},{"location":"man/projection/#.-List-of-functions","page":"Projection","title":"3. List of functions","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"GeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.Convert2UTMzone","category":"page"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2CartData","page":"Projection","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\nConvert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.ProjectCartData","page":"Projection","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = ProjectCartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2UTMzone","page":"Projection","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\nConvert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_UTM/#Read-in-UTM-data","page":"Read UTM data","title":"Read in UTM data","text":"","category":"section"},{"location":"man/tutorial_UTM/#Goal","page":"Read UTM data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004","category":"page"},{"location":"man/tutorial_UTM/#Steps","page":"Read UTM data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_UTM/#.-Download-and-import-UTM-data:","page":"Read UTM data","title":"1. Download and import UTM data:","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)\t\t\t\t\t\n# when using the data please cite as: \t\t\t\t\t\n# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004\nX COORD (UTM Zone 32N)\tY COORD (UTM Zone 32N)\tTOP (m.a.s.l)\tTHICKNESS (m)\tDENSITY (Kg/m3)\n286635\t4898615\t-24823.2533\t70418.125\t3305\n286635\t4918615\t-25443.48901\t69410.01563\t3305\n286635\t4938615\t-28025.24511\t66402.49219\t3305\n286635\t4958615\t-32278.13135\t61663.48438\t3305\n286635\t4978615\t-35885.5625\t57459.14063\t3305\n286635\t4998615\t-37270.9812\t55318.71094\t3305\n286635\t5018615\t-36134.30481\t55497.16406\t3305\n286635\t5038615\t-34866.0697\t55555.41406\t3305","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data=readdlm(\"2019-004_Spooner_Lithospheric Mantle.txt\",skipstart=4)\n1023×5 Matrix{Float64}:\n 286635.0 4.89862e6 -24823.3 70418.1 3305.0\n 286635.0 4.91862e6 -25443.5 69410.0 3305.0\n 286635.0 4.93862e6 -28025.2 66402.5 3305.0\n 286635.0 4.95862e6 -32278.1 61663.5 3305.0\n ⋮ \n 926635.0 5.45862e6 -35302.7 83215.6 3335.0\n 926635.0 5.47862e6 -34908.6 84203.0 3335.0\n 926635.0 5.49862e6 -34652.4 85398.3 3335.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> ew, ns, depth, thick, rho = data[:,1], data[:,2], data[:,3], data[:,4], data[:,5];","category":"page"},{"location":"man/tutorial_UTM/#.-Check-and-reshape-vertical-velocity","page":"Read UTM data","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> res = ( length(unique(ns)), length(unique(ew)), 1)\njulia> EW = reshape(ew,res) \njulia> NS = reshape(ns,res)\njulia> Depth = reshape(depth,res)\njulia> T = reshape(thick,res)\njulia> Rho = reshape(rho,res)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can examine EW: ","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW\n31×33×1 Array{Float64, 3}:\n[:, :, 1] =\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n ⋮ ⋮ ⋱ ⋮ \n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW = permutedims(EW,[2 1 3]) \njulia> NS = permutedims(NS,[2 1 3]) \njulia> Depth = permutedims(Depth,[2 1 3]) \njulia> T = permutedims(T,[2 1 3]) \njulia> Rho = permutedims(Rho,[2 1 3]) ","category":"page"},{"location":"man/tutorial_UTM/#.-Create-UTMData-structure","page":"Read UTM data","title":"3. Create UTMData structure","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can add the data to the UTMData structure. In this, we use the information that the UTM zone was 32 North.","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM = UTMData(EW,NS,Depth,32, true, (Thickness=T/1e3*km, Density=Rho*kg/m^3 ))\nUTMData \n UTM zone : 32-32 North\n size : (33, 31, 1)\n EW ϵ [ 286635.0 : 926635.0]\n NS ϵ [ 4.898615e6 : 5.498615e6]\n depth ϵ [ -52579.56788 m : -20873.400850000003 m]\n fields : (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/#.-Saving-and-plotting-in-Paraview","page":"Read UTM data","title":"4. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can transfer this into a GeoData structure as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM_lonlat = convert(GeoData,Data_LM)\nGeoData \n size : (33, 31, 1)\n lon ϵ [ 6.046903388679526 : 14.892535147436673]\n lat ϵ [ 44.11618022783332 : 49.64004892531006]\n depth ϵ [ -52.57956788 km : -20.873400850000003 km]\n fields: (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"and save it to Paraview in the usual way","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Write_Paraview(Data_LM_lonlat, \"Data_LM_lonlat\")","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Opening and plotting the vertical field gives: (Image: Tutorial_UTM)","category":"page"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nAdd lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.Save_LaMEMTopography\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.ReadData_PVTR\nGeophysicalModelGenerator.AddBox!\nGeophysicalModelGenerator.AddSphere!\nGeophysicalModelGenerator.AddEllipsoid!\nGeophysicalModelGenerator.AddCylinder!\nGeophysicalModelGenerator.makeVolcTopo\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.Compute_Phase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.CreatePartitioningFile","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file)\n\nParses a LaMEM input file and stores grid information in the Grid structure.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\") \nLaMEM Grid: \nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMTopography","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMTopography","text":"Save_LaMEMTopography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::ParaviewData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddBox!","page":"LaMEM","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddSphere!","page":"LaMEM","title":"GeophysicalModelGenerator.AddSphere!","text":"AddSphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddSphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddEllipsoid!","page":"LaMEM","title":"GeophysicalModelGenerator.AddEllipsoid!","text":"AddEllipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, axes=Tuple{3},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddEllipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddCylinder!","page":"LaMEM","title":"GeophysicalModelGenerator.AddCylinder!","text":"AddCylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base=Tuple{3}, cap=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddCylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.makeVolcTopo","page":"LaMEM","title":"GeophysicalModelGenerator.makeVolcTopo","text":"makeVolcTopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by ReadLaMEM_InputFile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData \n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData \n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Write_Paraview(Topo,\"VolcanoTopo\") # Save topography to paraview \nSaved file: VolcanoTopo.vts \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantTemp","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LinearTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LinearTemp","text":"LinearTemp(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"LaMEM","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCoolingTemp(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.SpreadingRateTemp","page":"LaMEM","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantPhase","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.Compute_Phase","page":"LaMEM","title":"GeophysicalModelGenerator.Compute_Phase","text":"Phase = Compute_Phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = Compute_Phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericPhases","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 15], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : The thickness of each layer, ordered from top to bottom. The thickness of the last layer does not have to be specified.\nPhases : The phases of the layers, ordered from top to bottom.\nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab are set to Phases[end].\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.CreatePartitioningFile","page":"LaMEM","title":"GeophysicalModelGenerator.CreatePartitioningFile","text":"CreatePartitioningFile(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\")\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded. ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo([4,20,37,49], file=\"@earth_relief_01m.grd\")\nGeoData \n size : (960, 720, 1)\n lon ϵ [ 4.0 : 19.983333333333334]\n lat ϵ [ 37.0 : 48.983333333333334]\n depth ϵ [ -3.8725 km : 4.2495 km]\n fields: (:Topography,)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area. ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Write_Paraview(Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EditURL = \"/LaPalma_example.jl\"","category":"page"},{"location":"man/LaPalma_example/#Create-a-3D-LaMEM-setup-for-La-Palma","page":"Generating LaMEM model","title":"Create a 3D LaMEM setup for La Palma","text":"","category":"section"},{"location":"man/LaPalma_example/#Aim","page":"Generating LaMEM model","title":"Aim","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.","category":"page"},{"location":"man/LaPalma_example/#.-Load-data","page":"Generating LaMEM model","title":"1. Load data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We will use two types of data to create the model","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topography\nEarthquake locations","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We start with loading the required packages","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"using GeophysicalModelGenerator, JLD2\nusing GMT","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you managed to install GMT on your machine, you can automatically download the topography with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file=\"@earth_relief_03s.grd\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"pwd()","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"\"/Users/kausb/.julia/dev/GeophysicalModelGenerator/docs/src/scripts\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Load the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo=load(\"Topo_LaPalma.jld2\",\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from https://www.ign.es/web/ign/portal/vlc-catalogo). Download that here","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"data_all_EQ = load(\"EQ_Data.jld2\",\"data_all_EQ\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (6045,)\n lon ϵ [ -18.0341 : -17.6671]\n lat ϵ [ 28.3102 : 28.8144]\n depth ϵ [ NaN km : NaN km]\n fields: (:Magnitude, :TimeSinceJan1_2021)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write the data to paraview with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(data_all_EQ,\"data_all_EQ\",PointsData=true)\nWrite_Paraview(Topo,\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: data_all_EQ.vtu\nSaved file: Topo.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"As earthquakes are point-wise data, you have to specify this. (Image: LaPalma_EQTopo_GeoData) Note that this data is not in \"easy\" coordinates (see coordinate axis in the plot, where z is not pointing upwards).","category":"page"},{"location":"man/LaPalma_example/#.-Convert-data","page":"Generating LaMEM model","title":"2. Convert data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"proj = ProjectionPoint(Lon=-17.84, Lat=28.56)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ProjectionPoint(28.56, -17.84, 222158.69478000276, 3.1625327286383654e6, 28, true)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Once this is done you can convert the topographic data to the cartesian reference frame","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EQ_cart = Convert2CartData(data_all_EQ, proj);\nTopo_cart = Convert2CartData(Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (1921, 1441, 1)\n x ϵ [ -86.09445705828863 km : 73.67229892155609 km]\n y ϵ [ -63.5531883197492 km : 73.28446155584604 km]\n z ϵ [ -4.38297802734375 km : 2.414 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, the routine ProjectCartData projects a GeoData structure to a CartData struct","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (701, 651, 1)\n x ϵ [ -70.0 km : 70.0 km]\n y ϵ [ -60.0 km : 70.0 km]\n z ϵ [ -4.29541702331831 km : 2.3840784607152257 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Let's have a look at the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(EQ_cart,\"EQ_cart\",PointsData=true)\nWrite_Paraview(Topo_LaMEM,\"Topo_LaMEM\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: EQ_cart.vtu\nSaved file: Topo_LaMEM.vts\n","category":"page"},{"location":"man/LaPalma_example/#.-Create-LaMEM-setup","page":"Generating LaMEM model","title":"3. Create LaMEM setup","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Grid = ReadLaMEM_InputFile(\"LaPalma.dat\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"LaMEM Grid: \n nel : (64, 64, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 192, 192)\n x ϵ [-50.0 : 50.0]\n y ϵ [-40.0 : 40.0]\n z ϵ [-80.0 : 15.0]\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Phases = ones(Int32,size(Grid.X))*2;\nTemp = ones(Float64,size(Grid.X));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Geotherm = 30;\nTemp = -Grid.Z.*Geotherm;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Temp[Temp.<20] .= 20;\nTemp[Temp.>1350] .= 1350;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to \"mantle\":","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( Grid.Z .< -40);\nPhases[ind] .= 3;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Everything above the free surface is assumed to be \"air\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = AboveSurface(Grid, Topo_cart);\nPhases[ind] .= 0;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And all \"air\" points that are below sea-level becomes \"water\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( (Phases.==0) .& (Grid.Z .< 0));\nPhases[ind] .= 1;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Looking at the seismicity, there is a swarm at around 35 km depth","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"A shallower one exists as well","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And there might be a mid-crustal one","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can generate a 3D model setup, which must include the Phases and Temp arrays","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\nWrite_Paraview(Model3D,\"Model3D\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: Model3D.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The model setup looks like this (Image: LaMEM_ModelSetup_LaPalma)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can create a LaMEM marker file from the Model3D setup and the (cartesian) topography","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Save_LaMEMTopography(Topo_cart, \"Topography.txt\")\nSave_LaMEMMarkersParallel(Model3D)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Written LaMEM topography file: Topography.txt\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.\nCreate movies for representation of earthquake or wave propagation.\nCreate geodynamic input models (for LaMEM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.4.7/siteinfo.js b/v0.4.7/siteinfo.js
new file mode 100644
index 00000000..362263bd
--- /dev/null
+++ b/v0.4.7/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.4.7";
diff --git a/v0.4.8/assets/documenter.js b/v0.4.8/assets/documenter.js
new file mode 100644
index 00000000..15dc682b
--- /dev/null
+++ b/v0.4.8/assets/documenter.js
@@ -0,0 +1,264 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia.min',
+ 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/headroom.min',
+ 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min',
+ 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/contrib/auto-render.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.10.3/jQuery.headroom.min',
+ 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min',
+ 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min',
+ 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/languages/julia-repl.min',
+ },
+ shim: {
+ "highlight-julia": {
+ "deps": [
+ "highlight"
+ ]
+ },
+ "katex-auto-render": {
+ "deps": [
+ "katex"
+ ]
+ },
+ "headroom-jquery": {
+ "deps": [
+ "jquery",
+ "headroom"
+ ]
+ },
+ "highlight-julia-repl": {
+ "deps": [
+ "highlight"
+ ]
+ }
+}
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) {
+$(document).ready(function() {
+ renderMathInElement(
+ document.body,
+ {
+ "delimiters": [
+ {
+ "left": "$",
+ "right": "$",
+ "display": false
+ },
+ {
+ "left": "$$",
+ "right": "$$",
+ "display": true
+ },
+ {
+ "left": "\\[",
+ "right": "\\]",
+ "display": true
+ }
+ ]
+}
+
+ );
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl'], function($, hljs) {
+$(document).ready(function() {
+ hljs.initHighlighting();
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) {
+
+// Manages the top navigation bar (hides it when the user starts scrolling down on the
+// mobile).
+window.Headroom = Headroom; // work around buggy module loading?
+$(document).ready(function() {
+ $('#documenter .docs-navbar').headroom({
+ "tolerance": {"up": 10, "down": 10},
+ });
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Modal settings dialog
+$(document).ready(function() {
+ var settings = $('#documenter-settings');
+ $('#documenter-settings-button').click(function(){
+ settings.toggleClass('is-active');
+ });
+ // Close the dialog if X is clicked
+ $('#documenter-settings button.delete').click(function(){
+ settings.removeClass('is-active');
+ });
+ // Close dialog if ESC is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) settings.removeClass('is-active');
+ });
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function() {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button")
+ sidebar_button.click(function(ev) {
+ ev.preventDefault();
+ sidebar.toggleClass('visible');
+ if (sidebar.hasClass('visible')) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind('click', function(ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass('visible')) {
+ sidebar.removeClass('visible');
+ }
+ });
+})
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function() {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css('max-width'), 10);
+ var L0 = e.width();
+ if(L0 > L) {
+ var h0 = parseInt(e.css('font-size'), 10);
+ e.css('font-size', L * h0 / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on('orientationchange', resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function() {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if(typeof active !== 'undefined') {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+function set_theme(theme) {
+ var active = null;
+ var disabled = [];
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ var ss = document.styleSheets[i];
+ var themename = ss.ownerNode.getAttribute("data-theme-name");
+ if(themename === null) continue; // ignore non-theme stylesheets
+ // Find the active theme
+ if(themename === theme) active = ss;
+ else disabled.push(ss);
+ }
+ if(active !== null) {
+ active.disabled = false;
+ if(active.ownerNode.getAttribute("data-theme-primary") === null) {
+ document.getElementsByTagName('html')[0].className = "theme--" + theme;
+ } else {
+ document.getElementsByTagName('html')[0].className = "";
+ }
+ disabled.forEach(function(ss){
+ ss.disabled = true;
+ });
+ }
+
+ // Store the theme in localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ window.localStorage.setItem("documenter-theme", theme);
+ } else {
+ console.error("Browser does not support window.localStorage");
+ }
+}
+
+// Theme picker setup
+$(document).ready(function() {
+ // onchange callback
+ $('#documenter-themepicker').change(function themepick_callback(ev){
+ var themename = $('#documenter-themepicker option:selected').attr('value');
+ set_theme(themename);
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if(typeof(window.localStorage) !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if(theme !== null) {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = (e.value === theme);
+ })
+ } else {
+ $('#documenter-themepicker option').each(function(i,e) {
+ e.selected = $("html").hasClass(`theme--${e.value}`);
+ })
+ }
+ }
+})
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function() {
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function(x) {
+ target_href = version_selector_select.children("option:selected").get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (typeof DOCUMENTER_CURRENT_VERSION !== 'undefined' && $('#version-selector > option').length == 0) {
+ var option = $("");
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== 'undefined') {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function(i,x){return x.text});
+ DOC_VERSIONS.forEach(function(each) {
+ var version_url = documenterBaseURL + "/../" + each;
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $("");
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+})
+
+})
diff --git a/v0.4.8/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png b/v0.4.8/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png
new file mode 100644
index 00000000..37c08e8d
Binary files /dev/null and b/v0.4.8/assets/img/Bildschirmfoto 2021-06-28 um 11.37.18.png differ
diff --git a/v0.4.8/assets/img/Digitizer_1.png b/v0.4.8/assets/img/Digitizer_1.png
new file mode 100644
index 00000000..5f731462
Binary files /dev/null and b/v0.4.8/assets/img/Digitizer_1.png differ
diff --git a/v0.4.8/assets/img/Digitizer_2.png b/v0.4.8/assets/img/Digitizer_2.png
new file mode 100644
index 00000000..59837df0
Binary files /dev/null and b/v0.4.8/assets/img/Digitizer_2.png differ
diff --git a/v0.4.8/assets/img/Digitizer_3.png b/v0.4.8/assets/img/Digitizer_3.png
new file mode 100644
index 00000000..24725997
Binary files /dev/null and b/v0.4.8/assets/img/Digitizer_3.png differ
diff --git a/v0.4.8/assets/img/Fig13_mapview.png b/v0.4.8/assets/img/Fig13_mapview.png
new file mode 100644
index 00000000..d075acba
Binary files /dev/null and b/v0.4.8/assets/img/Fig13_mapview.png differ
diff --git a/v0.4.8/assets/img/Flegrei_Geomorphology.png b/v0.4.8/assets/img/Flegrei_Geomorphology.png
new file mode 100644
index 00000000..c145ff48
Binary files /dev/null and b/v0.4.8/assets/img/Flegrei_Geomorphology.png differ
diff --git a/v0.4.8/assets/img/Flegrei_Noise.png b/v0.4.8/assets/img/Flegrei_Noise.png
new file mode 100644
index 00000000..6150ac2e
Binary files /dev/null and b/v0.4.8/assets/img/Flegrei_Noise.png differ
diff --git a/v0.4.8/assets/img/Flegrei_Seismicity.png b/v0.4.8/assets/img/Flegrei_Seismicity.png
new file mode 100644
index 00000000..30675ff4
Binary files /dev/null and b/v0.4.8/assets/img/Flegrei_Seismicity.png differ
diff --git a/v0.4.8/assets/img/Flegrei_VpVs.png b/v0.4.8/assets/img/Flegrei_VpVs.png
new file mode 100644
index 00000000..a4436fc6
Binary files /dev/null and b/v0.4.8/assets/img/Flegrei_VpVs.png differ
diff --git a/v0.4.8/assets/img/LaMEM_ModelSetup_LaPalma.png b/v0.4.8/assets/img/LaMEM_ModelSetup_LaPalma.png
new file mode 100644
index 00000000..863a18a8
Binary files /dev/null and b/v0.4.8/assets/img/LaMEM_ModelSetup_LaPalma.png differ
diff --git a/v0.4.8/assets/img/Lippitsch_Fig13a.png b/v0.4.8/assets/img/Lippitsch_Fig13a.png
new file mode 100644
index 00000000..a9be1ebc
Binary files /dev/null and b/v0.4.8/assets/img/Lippitsch_Fig13a.png differ
diff --git a/v0.4.8/assets/img/Readme_pic.png b/v0.4.8/assets/img/Readme_pic.png
new file mode 100644
index 00000000..61fd8a00
Binary files /dev/null and b/v0.4.8/assets/img/Readme_pic.png differ
diff --git a/v0.4.8/assets/img/TopoEQs_LaPalma_GeoData.png b/v0.4.8/assets/img/TopoEQs_LaPalma_GeoData.png
new file mode 100644
index 00000000..9ac618c6
Binary files /dev/null and b/v0.4.8/assets/img/TopoEQs_LaPalma_GeoData.png differ
diff --git a/v0.4.8/assets/img/Topo_Europe_CartData.png b/v0.4.8/assets/img/Topo_Europe_CartData.png
new file mode 100644
index 00000000..29f75dd0
Binary files /dev/null and b/v0.4.8/assets/img/Topo_Europe_CartData.png differ
diff --git a/v0.4.8/assets/img/Topo_Europe_CartData_Proj.png b/v0.4.8/assets/img/Topo_Europe_CartData_Proj.png
new file mode 100644
index 00000000..f79fdf09
Binary files /dev/null and b/v0.4.8/assets/img/Topo_Europe_CartData_Proj.png differ
diff --git a/v0.4.8/assets/img/Topo_Europe_GeoData.png b/v0.4.8/assets/img/Topo_Europe_GeoData.png
new file mode 100644
index 00000000..d4ef347c
Binary files /dev/null and b/v0.4.8/assets/img/Topo_Europe_GeoData.png differ
diff --git a/v0.4.8/assets/img/Topo_Europe_UTMData.png b/v0.4.8/assets/img/Topo_Europe_UTMData.png
new file mode 100644
index 00000000..3dc6756e
Binary files /dev/null and b/v0.4.8/assets/img/Topo_Europe_UTMData.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Coastlines.png b/v0.4.8/assets/img/Tutorial_Coastlines.png
new file mode 100644
index 00000000..c6c16a55
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Coastlines.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png
new file mode 100644
index 00000000..c7721ac8
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png
new file mode 100644
index 00000000..4a9757f0
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_2.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png
new file mode 100644
index 00000000..fa80fe95
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_1.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png
new file mode 100644
index 00000000..ef6f7313
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png
new file mode 100644
index 00000000..09a61f56
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ElSharkawy_MeRe_DataPoints_interpolated.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GMT_topography.png b/v0.4.8/assets/img/Tutorial_GMT_topography.png
new file mode 100644
index 00000000..de92484f
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GMT_topography.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap.png b/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap.png
new file mode 100644
index 00000000..02e1a98a
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png b/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png
new file mode 100644
index 00000000..755cc15d
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GMT_topography_GeologicalMap_PNG.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GPS_1.png b/v0.4.8/assets/img/Tutorial_GPS_1.png
new file mode 100644
index 00000000..cb21252d
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GPS_1.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GPS_2.png b/v0.4.8/assets/img/Tutorial_GPS_2.png
new file mode 100644
index 00000000..d847aa8f
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GPS_2.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GPS_3.png b/v0.4.8/assets/img/Tutorial_GPS_3.png
new file mode 100644
index 00000000..38ab3565
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GPS_3.png differ
diff --git a/v0.4.8/assets/img/Tutorial_GPS_4.png b/v0.4.8/assets/img/Tutorial_GPS_4.png
new file mode 100644
index 00000000..1160a5b2
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_GPS_4.png differ
diff --git a/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat.png b/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat.png
new file mode 100644
index 00000000..080f03f8
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat.png differ
diff --git a/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png b/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png
new file mode 100644
index 00000000..708c5239
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_MohoSpada_LonLat_Paraview.png differ
diff --git a/v0.4.8/assets/img/Tutorial_MohoSpada_Surface_Paraview.png b/v0.4.8/assets/img/Tutorial_MohoSpada_Surface_Paraview.png
new file mode 100644
index 00000000..45c52ca8
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_MohoSpada_Surface_Paraview.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_1.png b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_1.png
new file mode 100644
index 00000000..472e68cd
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_1.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_3.png b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_3.png
new file mode 100644
index 00000000..4af40b37
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_3.png differ
diff --git a/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_4.png b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_4.png
new file mode 100644
index 00000000..03b2c01e
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_ScreenShots_Lippitsch_4.png differ
diff --git a/v0.4.8/assets/img/Tutorial_SeismicityTime_1.png b/v0.4.8/assets/img/Tutorial_SeismicityTime_1.png
new file mode 100644
index 00000000..69b25f21
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_SeismicityTime_1.png differ
diff --git a/v0.4.8/assets/img/Tutorial_SeismicityTime_2.png b/v0.4.8/assets/img/Tutorial_SeismicityTime_2.png
new file mode 100644
index 00000000..09252190
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_SeismicityTime_2.png differ
diff --git a/v0.4.8/assets/img/Tutorial_SeismicityTime_3.mov b/v0.4.8/assets/img/Tutorial_SeismicityTime_3.mov
new file mode 100644
index 00000000..04ed003e
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_SeismicityTime_3.mov differ
diff --git a/v0.4.8/assets/img/Tutorial_UTM.png b/v0.4.8/assets/img/Tutorial_UTM.png
new file mode 100644
index 00000000..271b680f
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_UTM.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Visualize.png b/v0.4.8/assets/img/Tutorial_Visualize.png
new file mode 100644
index 00000000..df919f45
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Visualize.png differ
diff --git a/v0.4.8/assets/img/Tutorial_VoteMap.png b/v0.4.8/assets/img/Tutorial_VoteMap.png
new file mode 100644
index 00000000..2e318e6a
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_VoteMap.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data.png b/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data.png
new file mode 100644
index 00000000..bb9b2c87
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data_101km.png b/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data_101km.png
new file mode 100644
index 00000000..bcc0836f
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_LatLon_data_101km.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_1.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_1.png
new file mode 100644
index 00000000..db9412b9
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_1.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_2.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_2.png
new file mode 100644
index 00000000..84e11ad3
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_2.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_3.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_3.png
new file mode 100644
index 00000000..4804e9bf
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_3.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_4.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_4.png
new file mode 100644
index 00000000..cad08ac0
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_4.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_5.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_5.png
new file mode 100644
index 00000000..90b7dd22
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_5.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_6.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_6.png
new file mode 100644
index 00000000..7ef5762c
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_6.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_7.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_7.png
new file mode 100644
index 00000000..8789e095
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_7.png differ
diff --git a/v0.4.8/assets/img/Tutorial_Zhao_Paraview_8.png b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_8.png
new file mode 100644
index 00000000..8943b1b6
Binary files /dev/null and b/v0.4.8/assets/img/Tutorial_Zhao_Paraview_8.png differ
diff --git a/v0.4.8/assets/search.js b/v0.4.8/assets/search.js
new file mode 100644
index 00000000..71ebd87e
--- /dev/null
+++ b/v0.4.8/assets/search.js
@@ -0,0 +1,251 @@
+// Generated by Documenter.jl
+requirejs.config({
+ paths: {
+ 'lunr': 'https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.6/lunr.min',
+ 'lodash': 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min',
+ 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min',
+ }
+});
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery', 'lunr', 'lodash'], function($, lunr, _) {
+
+$(document).ready(function() {
+ // parseUri 1.2.2
+ // (c) Steven Levithan
+ // MIT License
+ function parseUri (str) {
+ var o = parseUri.options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ };
+ parseUri.options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ $("#search-form").submit(function(e) {
+ e.preventDefault()
+ })
+
+ // list below is the lunr 2.1.3 list minus the intersect with names(Base)
+ // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with)
+ // ideally we'd just filter the original list but it's not available as a variable
+ lunr.stopWordFilter = lunr.generateStopWordFilter([
+ 'a',
+ 'able',
+ 'about',
+ 'across',
+ 'after',
+ 'almost',
+ 'also',
+ 'am',
+ 'among',
+ 'an',
+ 'and',
+ 'are',
+ 'as',
+ 'at',
+ 'be',
+ 'because',
+ 'been',
+ 'but',
+ 'by',
+ 'can',
+ 'cannot',
+ 'could',
+ 'dear',
+ 'did',
+ 'does',
+ 'either',
+ 'ever',
+ 'every',
+ 'from',
+ 'got',
+ 'had',
+ 'has',
+ 'have',
+ 'he',
+ 'her',
+ 'hers',
+ 'him',
+ 'his',
+ 'how',
+ 'however',
+ 'i',
+ 'if',
+ 'into',
+ 'it',
+ 'its',
+ 'just',
+ 'least',
+ 'like',
+ 'likely',
+ 'may',
+ 'me',
+ 'might',
+ 'most',
+ 'must',
+ 'my',
+ 'neither',
+ 'no',
+ 'nor',
+ 'not',
+ 'of',
+ 'off',
+ 'often',
+ 'on',
+ 'or',
+ 'other',
+ 'our',
+ 'own',
+ 'rather',
+ 'said',
+ 'say',
+ 'says',
+ 'she',
+ 'should',
+ 'since',
+ 'so',
+ 'some',
+ 'than',
+ 'that',
+ 'the',
+ 'their',
+ 'them',
+ 'then',
+ 'there',
+ 'these',
+ 'they',
+ 'this',
+ 'tis',
+ 'to',
+ 'too',
+ 'twas',
+ 'us',
+ 'wants',
+ 'was',
+ 'we',
+ 'were',
+ 'what',
+ 'when',
+ 'who',
+ 'whom',
+ 'why',
+ 'will',
+ 'would',
+ 'yet',
+ 'you',
+ 'your'
+ ])
+
+ // add . as a separator, because otherwise "title": "Documenter.Anchors.add!"
+ // would not find anything if searching for "add!", only for the entire qualification
+ lunr.tokenizer.separator = /[\s\-\.]+/
+
+ // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names
+ lunr.trimmer = function (token) {
+ return token.update(function (s) {
+ return s.replace(/^[^a-zA-Z0-9@!]+/, '').replace(/[^a-zA-Z0-9@!]+$/, '')
+ })
+ }
+
+ lunr.Pipeline.registerFunction(lunr.stopWordFilter, 'juliaStopWordFilter')
+ lunr.Pipeline.registerFunction(lunr.trimmer, 'juliaTrimmer')
+
+ var index = lunr(function () {
+ this.ref('location')
+ this.field('title',{boost: 100})
+ this.field('text')
+ documenterSearchIndex['docs'].forEach(function(e) {
+ this.add(e)
+ }, this)
+ })
+ var store = {}
+
+ documenterSearchIndex['docs'].forEach(function(e) {
+ store[e.location] = {title: e.title, category: e.category, page: e.page}
+ })
+
+ $(function(){
+ searchresults = $('#documenter-search-results');
+ searchinfo = $('#documenter-search-info');
+ searchbox = $('#documenter-search-query');
+ function update_search(querystring) {
+ tokens = lunr.tokenizer(querystring)
+ results = index.query(function (q) {
+ tokens.forEach(function (t) {
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 100,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["title"],
+ boost: 10,
+ usePipeline: true,
+ editDistance: 2,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ q.term(t.toString(), {
+ fields: ["text"],
+ boost: 1,
+ usePipeline: true,
+ editDistance: 0,
+ wildcard: lunr.Query.wildcard.NONE
+ })
+ })
+ })
+ searchinfo.text("Number of results: " + results.length)
+ searchresults.empty()
+ results.forEach(function(result) {
+ data = store[result.ref]
+ link = $(''+data.title+'')
+ link.attr('href', documenterBaseURL+'/'+result.ref)
+ if (data.category != "page"){
+ cat = $('('+data.category+', '+data.page+')')
+ } else {
+ cat = $('('+data.category+')')
+ }
+ li = $('
The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.
For this, GeophysicalModelGenerator provides the following functionality:
A consistent GeoData structure, that holds the data along with lon/lat/depth information.
Routines to generate VTK files from the GeoData structure in order to visualize results in Paraview.
The ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.
Rapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.
Create movies for representation of earthquake or wave propagation.
Create geodynamic input models (for LaMEM)
The best way to get started is to look at the tutorials.
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
diff --git a/v0.4.8/man/LaPalma_example/index.html b/v0.4.8/man/LaPalma_example/index.html
new file mode 100644
index 00000000..05d66a5f
--- /dev/null
+++ b/v0.4.8/man/LaPalma_example/index.html
@@ -0,0 +1,68 @@
+
+Generating LaMEM model · GeophysicalModelGenerator.jl
In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.
In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:
As earthquakes are point-wise data, you have to specify this. Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where z is not pointing upwards).
In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
CartData
+ size : (1921, 1441, 1)
+ x ϵ [ -86.09445705828863 km : 73.67229892155609 km]
+ y ϵ [ -63.5531883197492 km : 73.28446155584604 km]
+ z ϵ [ -4.38297802734375 km : 2.414 km]
+ fields : (:Topography,)
+
It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:
In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command
Grid = ReadLaMEM_InputFile("LaPalma.dat")
LaMEM Grid:
+ nel : (64, 64, 32)
+ marker/cell : (3, 3, 3)
+ markers : (192, 192, 192)
+ x ϵ [-50.0 : 50.0]
+ y ϵ [-40.0 : 40.0]
+ z ϵ [-80.0 : 15.0]
+
The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.
In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.
Looking at the seismicity, there is a swarm at around 35 km depth
Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.
Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory
The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
Everything that fulfills this criteria gets the number 1, everything else 0.
Do the same with other tomographic models (using the same criteria or a different one).
Make sure that all tomographic models are interpolated to the same grid.
Sum up the 3 models.
The resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
So how do we create Votemaps? Doing this is rather simple:
This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:
And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
Write_Paraview(Data_VoteMap, "VoteMap_Alps")
In paraview, this gives
You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:
Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
Take a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview
The lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).
The lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.
Note: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).
The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.
Data structure that holds one or several fields with longitude, latitude and depth information.
depth can have units of meter, kilometer or be unitless; it will be converted to km.
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Example
julia> Lat = 1.0:3:10.0;
+julia> Lon = 11.0:4:20.0;
+julia> Depth = (-20:5:-10)*km;
+julia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);
+julia> Lon3D
+3×4×3 Array{Float64, 3}:
+[:, :, 1] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 2] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+
+[:, :, 3] =
+ 11.0 11.0 11.0 11.0
+ 15.0 15.0 15.0 15.0
+ 19.0 19.0 19.0 19.0
+julia> Lat3D
+ 3×4×3 Array{Float64, 3}:
+ [:, :, 1] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 2] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+
+ [:, :, 3] =
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+ 1.0 4.0 7.0 10.0
+julia> Depth3D
+ 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:
+ [:, :, 1] =
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+ -20.0 km -20.0 km -20.0 km -20.0 km
+
+ [:, :, 2] =
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+ -15.0 km -15.0 km -15.0 km -15.0 km
+
+ [:, :, 3] =
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+ -10.0 km -10.0 km -10.0 km -10.0 km
+julia> Data = zeros(size(Lon3D));
+julia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,))
+GeoData
+ size : (3, 4, 3)
+ lon ϵ [ 11.0 : 19.0]
+ lat ϵ [ 1.0 : 10.0]
+ depth ϵ [ -20.0 km : -10.0 km]
+ fields : (:DataFieldName,)
+ attributes: ["note"]
Data structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.
depth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
Lat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.
Cartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:
Data structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers
x,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers
fields should ideally be a NamedTuple which allows you to specify the names of each of the fields.
In case you only pass one array we will convert it to a NamedTuple with default name.
A single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).
Multiple fields can be added as well.
In case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.
Yet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors.
x,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.
Example
julia> x = 0:2:10
+julia> y = -5:5
+julia> z = -10:2:2
+julia> X,Y,Z = XYZGrid(x, y, z);
+julia> Data = Z
+julia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))
+CartData
+ size : (6, 11, 7)
+ x ϵ [ 0.0 km : 10.0 km]
+ y ϵ [ -5.0 km : 5.0 km]
+ z ϵ [ -10.0 km : 2.0 km]
+ fields : (:FakeData, :Data2)
+ attributes: ["note"]
CartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with
voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};
+refMod="AVG", lengthUnit="m", rhoTol=1e-9, Topo=[], outName="Bouguer", printing=true)
+
+Computes Bouguer anomalies and gradients
+
+Required arguments:
+X,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid)
+RHO: 3D matrix with the densitiy at each grid point [kg/m^3]
+
+Optional arguments:
+refMod: 1D vector with the reference density for each depth
+ Alternatively, the strings "NE", "SE", "SW", "NW", "AVG" can be used.
+ In that case, one of the corners of `RHO` is used as reference model.
+ In case of "AVG" the reference model is the average of each depth slice.
+lengthUnit: The unit of the coordinates and topography file. Either "m" or "km"
+rhoTol: density differences smaller than rhoTol will be ignored [kg/m^3]
+Topo: 2D matrix with the topography of the surface (only relevant for the paraview output)
+outName: name of the paraview output (do not include file type)
+printing: activate printing of additional information [true or false]
GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.
The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).
From the julia prompt, you start the package manager by typing ]:
(@v1.6) pkg>
And you return to the command line with a backspace.
Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:
julia>;
+shell>
In the shell, you can use the normal commands like listing the content of a directory, or the current path:
shell> ls
+LICENSE Manifest.toml Project.toml README.md docs src test tutorial
+shell> pwd
+/Users/kausb/.julia/dev/GeophysicalModelGenerator
As before, return to the main command line (called REPL) with a backspace.
If you want to see help information for any julia function, type ? followed by the command. An example for tan is:
help?> tan
+search: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros
+
+ tan(x)
+
+ Compute tangent of x, where x is in radians.
+
+ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
+
+ tan(A::AbstractMatrix)
+
+ Compute the matrix tangent of a square matrix A.
+
+ If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.
+
+ Examples
+ ≡≡≡≡≡≡≡≡≡≡
+
+ julia> tan(fill(1.0, (2,2)))
+ 2×2 Matrix{Float64}:
+ -1.09252 -1.09252
+ -1.09252 -1.09252
If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:
This will automatically install various other packages it relies on (using the correct version).
If you want, you can test if it works on your machine by running the test suite in the package manager:
julia> ]
+(@v1.6) pkg> test GeophysicalModelGenerator
Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.
The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.
If you, at a later stage, want to upgrade to the latest version of GMG, you can type:
As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials.
If you already want to install some of those, here our favorites. Install them through the package manager:
GMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page.
The routines provided here have the following functionality:
Read LaMEM *.dat files (to get the size of the domain)
Read LaMEM processor partitioning file
Add lithospheric boxes to a setup, that may have a layered structure and various thermal structures
Saves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.
The size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.
Creates a generic volcano topography (cones and truncated cones)
Parameters
Grid - LaMEM grid (created by ReadLaMEM_InputFile)
center - x- and -coordinates of center of volcano
height - height of volcano
radius - radius of volcano
Optional Parameters
crater - this will create a truncated cone and the option defines the radius of the flat top
base - this sets the flat topography around the volcano
background - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)
This executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).
We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.
Writes a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd
If you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview
Individual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.
Example
Usually this is used inside a *.jl script, as in this pseudo-example:
movie = Movie_Paraview(name="Movie", Initialize=true)
+for itime=1:10
+ name = "test"*string(itime)
+ movie = Write_Paraview(Data, name, pvd=movie, time=itime)
+end
+Movie_Paraview(pvd=movie, Finalize=true)
Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).
If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid).
Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.
As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.
Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):
Whereas this is now in UTM Data (in meters), it is distorted.
Often it is more convenient to have this in CartData, which is done in a similar manner:
julia> Topo_Cart = Convert2CartData(Topo,p)
+CartData
+ size : (165, 75, 1)
+ x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]
+ y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]
+ z ϵ [ -4.9855 km : 3.123 km]
+ fields : (:Topography,)
This shows that the model is ~5600 by 3000 km.
Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal.
Projects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
Note:
If d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Projects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cartmust be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).
# Note:
+- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.
Converts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.
Cross-sections can be horizontal (map view at a given depth), if Depth_level is specified
They can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.
Depending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:
Volume data: data will be interpolated or directly extracted from the data set.
Surface data: surface data will be interpolated or directly extracted from the data set
Point data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used
Interpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC aND SURFACE DATA SETS
'section_width' indicates the maximal distance within which point data will be projected to the profile
Extract or "cuts-out" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.
This is useful if you are only interested in a part of a much bigger larger data set.
Lon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range.
By default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).
Alternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.
Creates a Vote map which shows consistent features in different 2D/3D tomographic datasets.
The way it works is:
Find a common region between the different GeoData sets (overlapping lon/lat/depth regions)
Interpolate the fields of all DataSets to common coordinates
Filter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.
Sum the results of the different datasets
If a feature is consistent between different datasets, it will have larger values.
Example
We assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:
Below = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)
+
+Determines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`
This parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers
Example
This example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:
julia> using CSV
+julia> data_file = CSV.File("FileName.txt",datarow=18,header=false,delim=' ')
+julia> data = ParseColumns_CSV_File(data_file, 4)
Computes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.
In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded.
The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area.
In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.
Note
It may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew).
The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt .
To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia:
julia>
+julia> using GMT
+julia> filename_gmt = "./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt"
+julia> plot(filename_gmt,region="4/20/37/49",show=true)
This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:
Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map):
At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:
The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid
The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:
Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:
Column 1: Longitude [degrees]
+Column 2: Latitude [degrees]
+Column 3: Velocity in the height direction [m/a]
+Column 4: Uncertainty of the height component [m/a]
+
+
+ 4.00 43.00 0.000067 0.000287
+ 4.30 43.00 -0.001000 0.000616
+ 4.60 43.00 -0.001067 0.000544
So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ALPS2017_DEF_VT.GRD",datarow=18,header=false,delim=' ');
We can read the numerical data from the file with:
So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:
julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)
So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.
julia> Ve = ones(size(Vz))*NaN;
+julia> Vn = ones(size(Vz))*NaN;
Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:
julia> for i in eachindex(lon_Hz)
+ ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))
+ Ve[ind] .= Ve_Hz[i];
+ Vn[ind] .= Vn_Hz[i];
+ end
At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:
At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.
Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:
julia> using GMT
+julia> Elevation = gmtread("@earth_relief_01m.grd", limits=[3,17,42,50]);
Next, we use the Interpolations.jl package to interpolate the topography:
At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:
In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like:
The arrows can now be colored by the individual velocity components or its magnitude.
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
diff --git a/v0.4.8/man/tutorial_ISC_data/index.html b/v0.4.8/man/tutorial_ISC_data/index.html
new file mode 100644
index 00000000..76ff25e2
--- /dev/null
+++ b/v0.4.8/man/tutorial_ISC_data/index.html
@@ -0,0 +1,8 @@
+
+ISC earthquake data · GeophysicalModelGenerator.jl
You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.
The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.
julia> using CSV, GeophysicalModelGenerator
+julia> data_file = CSV.File("ISC1.dat",datarow=24,header=false,delim=',')
As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.
This explains how to load the Moho topography for Italy and the Alps and create a paraview file
Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148
The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.
Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt
Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> scatter(lon,lat,marker_z=depth, ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.
The easiest way to transfer this to Paraview is to simply save this as 3D data points:
So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points
And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MohoTopo_Spada.jl")
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.
For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.
For this example, we use a well-known paper about the Alps which is now openly available:
Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016
Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:
The first step is to crop the image such that we only see the profile itself:
We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):
Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.
An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth):
Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.
If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a "multi-block" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:
The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from
Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004
Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:
# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)
+# when using the data please cite as:
+# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004
+X COORD (UTM Zone 32N) Y COORD (UTM Zone 32N) TOP (m.a.s.l) THICKNESS (m) DENSITY (Kg/m3)
+286635 4898615 -24823.2533 70418.125 3305
+286635 4918615 -25443.48901 69410.01563 3305
+286635 4938615 -28025.24511 66402.49219 3305
+286635 4958615 -32278.13135 61663.48438 3305
+286635 4978615 -35885.5625 57459.14063 3305
+286635 4998615 -37270.9812 55318.71094 3305
+286635 5018615 -36134.30481 55497.16406 3305
+286635 5038615 -34866.0697 55555.41406 3305
So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:
The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).
julia> res = ( length(unique(ns)), length(unique(ew)), 1)
+julia> EW = reshape(ew,res)
+julia> NS = reshape(ns,res)
+julia> Depth = reshape(depth,res)
+julia> T = reshape(thick,res)
+julia> Rho = reshape(rho,res)
So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:
This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in:
Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310
The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.
The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.
The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).
julia> using Plots
+julia> ind=findall(x -> x==-101.0, depth)
+julia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel="latitude",xlabel="longitude",markersize=2.5, c = :roma)
Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here.
Clearly, the data is given as regular Lat/Lon points:
In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it.
This visualisation employs the default colormap, which is not particularly good.
You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.
In order to change the colorrange select the button in the red ellipse and change the lower/upper bound.
If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
After pushing Apply, you'll see this:
If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.
In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.
There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:
As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.
If you wish to interpolate the data, specify Interpolate=true:
Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:
This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc.
By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:
It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:
julia> using JLD2
+julia> jldsave("Zhao_Pwave.jld2"; Data_set)
If you, at a later stage, want to load this file again do it as follows:
julia> using JLD2, GeophysicalModelGenerator
+julia> Data_set_Zhao2016_Vp = load_object("Zhao_Pwave.jld2")
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.
The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\n).
The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.
Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)
So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.
which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate
Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points.
There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with
julia> ]
+(@v1.6) pkg> add GeoStats
We will first show how to interpolate data @ 50 km depth.
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
diff --git a/v0.4.8/man/tutorial_loadregular3DSeismicData_netCDF/index.html b/v0.4.8/man/tutorial_loadregular3DSeismicData_netCDF/index.html
new file mode 100644
index 00000000..c9b2ac67
--- /dev/null
+++ b/v0.4.8/man/tutorial_loadregular3DSeismicData_netCDF/index.html
@@ -0,0 +1,83 @@
+
+3D seismic tomography from netCDF · GeophysicalModelGenerator.jl
This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:
El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G$^3$https://doi.org/10.1029/2020GC008993
The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:
julia> using Pkg
+julia> Pkg.add("NetCDF")
First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):
julia> using NetCDF
+julia> ncinfo("El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc")
+##### NetCDF File #####
+
+/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc
+
+##### Dimensions #####
+
+Name Length
+--------------------------------------------------------------------------------------------------------------------------
+depth 301
+latitude 100
+longitude 100
+
+##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
+
+##### Attributes #####
+
+Variable Name Value
+--------------------------------------------------------------------------------------------------------------------------
+global author_email amr.elsharkawy@ifg.uni-kiel.de
+global data_revision r.0.0
+global author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..
+global keywords seismic tomography, shear wave, Mediterranean, phase veloc..
+global acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..
+global history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..
+global repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1
+global id MeRE2020
+global author_name Amr EL-Sharkawy
+global comment model converted to netCDF by IRIS EMC
+global NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..
+global summary MeRE2020 is a high-resolution Shearâwave velocity mod..
+global repository_institution IRIS DMC
+global netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc
+global author_url https://www.seismologie.ifg.uni-kiel.de
+global reference El-Sharkawy, et al. (2020)
+global repository_name EMC
+global Conventions CF-1.0
+global Metadata_Conventions Unidata Dataset Discovery v1.0
+global title The Slab Puzzle of the AlpineâMediterranean Region: I..
+depth units km
+depth long_name depth in km
+depth display_name depth in km
+depth positive down
+latitude units degrees_north
+latitude long_name Latitude; positive north
+latitude standard_name latitude
+longitude units degrees_east
+longitude long_name Longitude; positive east
+longitude standard_name longitude
+Vs units km.s-1
+Vs long_name Shear wave velocity
+Vs display_name S Velocity (km/s)
As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:
##### Variables #####
+
+Name Type Dimensions
+--------------------------------------------------------------------------------------------------------------------------
+depth FLOAT depth
+latitude FLOAT latitude
+longitude FLOAT longitude
+Vs FLOAT longitude latitude depth
Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread:
In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:
Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);
In paraview you can open the file and visualize it:
Note that we employ the perceptually uniform color map Barlow, which you can download here.
If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).
The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with
julia> include("MeRe_ElSharkawy.jl")
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:
Two shape files containing coastline and faults:
Vilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508
Earthquake data for two volcanic unrests, in 1983-84 and 2005-2016:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
De Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817
Travel time tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Ambient noise tomography model:
Battaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x
Load both the the shape (.shp) files contained in "./Geomorphology/*.shp" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:
To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates
Now let's plot earthquake data provided as text files. Start loading the data contained in "./SeismicLocations/*.txt". The first column gives us a temporal marker we can use to plot earthquakes in different periods.
Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in "./TravelTmeTomography/modvPS.dat" for both cartesian and UTM coordinates.
Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files "./NoiseTomography/*.txt". We read them consecutively in a "for" loop:
julia> list_files = glob("AmbientNoiseTomography/*.txt");
+julia> li = size(list_files, 1);
+julia> for i = 1:li
+julia> nameFile = list_files[i];
+julia> name_vts = name_vts[24:26];
+julia> data = readdlm(nameFile, '\t', Float64);
+julia> WE = data[:,1];
+julia> SN = data[:,2];
+julia> depth = data[:,3];
+julia> Vs = data[:,4];
However these models are too wide, so it is better to constrain them:
julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );
+julia> WE = WE[ind];
+julia> SN = SN[ind];
+julia> depth = depth[ind];
+julia> Vs = Vs[ind];
Also, nodes are irregular, hence we create a 3D regular UTM:
This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:
Earthquake data for the 1983-84 unrest:
De Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7
You will need to download the zipped folder containing all files from here.
Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here
Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.
julia> using DelimitedFiles, GeophysicalModelGenerator, Dates
+julia> p2 = @__FILE__;
+julia> p2last = findlast("/",p2);
+julia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);
+julia> output_path = string(p3,"/");
+julia> movie = Movie_Paraview(name=string(p3,"/TemporalSeismicity"), Initialize=true);
+julia> if isdir(string(p3,"/TemporalSeismicity"))==0
+julia> mkdir(string(p3,"/TemporalSeismicity"));
+julia> end
+
Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.
julia> data = readdlm("SeismicLocations/Seismicity_UTM_1983_1984.txt", '\t', skipstart=0, header=false);
+julia> l = length(data[:,1]);
+julia> dates = Date.(zeros(l,1))
+julia> for i = 1:l
+julia> df = DateFormat("yyyymmdd");
+julia> t1 = string("19",@sprintf("%5.o", data[i,1]));
+julia> t2 = Date(t1[1:8],df);
+julia> dates[i,1] = t2;
+julia> end
+julia> WE = data[:,2];
+julia> SN = data[:,3];
+julia> depth = data[:,4];
+julia> dates_num = dates - dates[1];
+
Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.
julia> nt = 50;
+julia> dt = Dates.Day(nt);
+julia> t = minimum(dates):dt:maximum(dates);
+julia> for itime = 1:length(t)-1
+julia> name = string(p3,"/TemporalSeismicity/", string(itime));
+julia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);
+julia> we = WE[tt];
+julia> sn = SN[tt];
+julia> Depth1 = depth[tt];
+julia> DN = dates_num[tt];
+julia> label_time = Dates.value(DN[end]);
+julia> if size(tt,1)>1
+julia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));
+julia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);
+julia> end
+julia>end
+julia>Movie_Paraview(pvd=movie, Finalize=true)
+
This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.
Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.
If you want to run the entire example, you can find the .jl code here
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
Moho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.
Topography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.
Coastlines. Shows how to generate land/sea surfaces.
Import screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D
3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.
Topography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.
ISC earthquake data. Shows how to import earthquake data from the ISC catalogue.
Plot GPS data. Shows how to load and plot GPS data as vectors.
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.
It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:
julia> using GeophysicalModelGenerator, GLMakie
+julia> using GMT, JLD2
The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).
julia> ;
+shell> cd ~/Downloads/Zhao_etal_2016_data/
Now you can use the backspace key to return to the REPL, where we will load the data
julia> Data = JLD2.load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp");
At this stage you can look at it with
julia> Visualise(Data);
Note that this tends to take a while, the first time you do this (faster afterwards).
Let's add topography to the plot as well, which requires us to first load that:
This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.
And once we have done that, you can visualize the data in the same way:
julia> Visualise(Data_Cart, Topography=Topo_Cart)
Missing docstring.
Missing docstring for GeophysicalModelGenerator.Visualise. Check Documenter's build log for details.
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
diff --git a/v0.4.8/scripts/LaPalma.dat b/v0.4.8/scripts/LaPalma.dat
new file mode 100644
index 00000000..f64edccf
--- /dev/null
+++ b/v0.4.8/scripts/LaPalma.dat
@@ -0,0 +1,361 @@
+# Define number of elements in x, y, z-direction
+# Negative number implies corresponding number of mesh segments
+# Data is provided in the variables seg_x, seg_y, seg_z and includes:
+# * coordinates of the delimiters between the segments (n-1 points)
+# * number of cells (n points)
+# * bias coefficients (n points)
+
+
+#===============================================================================
+# Scaling
+#===============================================================================
+
+# Geometry
+units = geo
+
+# Always in SI units!!
+unit_temperature = 500
+unit_length = 1000
+unit_viscosity = 1e19
+unit_stress = 1e9
+
+#===============================================================================
+# Time stepping parameters
+#===============================================================================
+
+ dt = 5e-4 # time step
+ dt_min = 4.5e-4 # minimum time step (declare divergence if lower value is attempted)
+ dt_max = 1e-3 # maximum time step
+ inc_dt = 1 # time step increment per time step (fraction of unit)
+ CFL = 0.5 # CFL (Courant-Friedrichs-Lewy) criterion
+ CFLMAX = 0.8 # CFL criterion for elasticity
+ nstep_ini = 0 # save output for n initial steps
+ nstep_max = 20 # maximum allowed number of steps (lower bound: time_end/dt_max)
+ nstep_out = 1 # save output every n steps
+
+#===============================================================================
+# Grid & discretization parameters
+#===============================================================================
+
+# relative geometry tolerance for grid manipulations (default 1e-9)
+
+ gtol = 1e-9
+
+# Number of cells for all segments
+ nel_x = 64
+ nel_y = 64
+ nel_z = 32
+
+# Coordinates of all segments (including start and end points)
+ coord_x = -50 50
+ coord_y = -40 40
+ coord_z = -80 15
+
+#===============================================================================
+# Free surface
+#===============================================================================
+
+ surf_use = 1 # free surface activation flag
+ surf_corr_phase = 1 # air phase ratio correction flag (due to surface position)
+ surf_level = 5 # initial level
+ surf_air_phase = 0 # phase ID of sticky air layer
+ surf_max_angle = 45.0 # maximum angle with horizon (smoothed if larger)
+ surf_topo_file = LaPalma_Topo.topo # initial topography file (redundant)
+ erosion_model = 0 # erosion model [0-none (default), 1-infinitely fast]
+ sediment_model = 0 # sedimentation model [0-none (dafault), 1-prescribed rate]
+
+#===============================================================================
+# Boundary conditions
+#===============================================================================
+
+# noslip = 0 0 0 0 0 0
+
+ temp_top = 0 # Temperature @ top
+ temp_bot = 1350 # Temperature @ bottom; side BC's are flux-free
+
+ # Background strain rate parameters
+# exx_num_periods = 1 # number intervals of constant strain rate (x-axis)
+# exx_strain_rates = -5e-16 # strain rates for each interval (negative=compression)
+
+ # Free surface top boundary flag
+ open_top_bound = 1
+
+#===============================================================================
+# Jacobian & residual evaluation parameters
+#===============================================================================
+
+ gravity = 0.0 0.0 -9.81 # gravity vector
+ act_temp_diff = 1 # temperature diffusion activation flag
+ #act_steady_temp = 0 # steady-state temperature initial guess activation flag
+ #steady_temp_t = 0.1 # time for (quasi-)steady-state temperature initial guess
+ #nstep_steady = 50 # number of steps for (quasi-)steady-state temperature initial guess (default = 1)
+ act_heat_rech = 0 # heat recharge activation flag
+ init_lith_pres = 1 # initial pressure with lithostatic pressure
+ init_guess = 1 # initial guess flag
+ eta_min = 1e18 # viscosity upper bound
+ eta_max = 1e23 # viscosity lower limit
+ eta_ref = 1e19 # reference viscosity (initial guess)
+ T_ref = 20 # reference temperature
+
+#===============================================================================
+# Solver options
+#===============================================================================
+
+ SolverType = multigrid # solver [direct or multigrid]
+ MGLevels = 4 # number of MG levels [default=3]
+
+#===============================================================================
+# Model setup & advection
+#===============================================================================
+
+ msetup = files
+ mark_load_file = ./markers/mdb # marker input file (extension is .xxxxxxxx.dat)
+
+ #poly_file = ../Polygons/RoundTopShort_256_128_21_09_20.bin
+ nmark_x = 3 # markers per cell in x-direction
+ nmark_y = 3 # ... y-direction
+ nmark_z = 3 # ... z-direction
+# rand_noise = 1 # random noise flag
+ advect = rk2 # advection scheme
+ interp = minmod # velocity interpolation scheme
+# stagp_a = 0.7 # STAG_P velocity interpolation parameter
+ mark_ctrl = basic # marker control type
+ nmark_lim = 16 100 # min/max number per cell
+
+#===============================================================================
+# Output
+#===============================================================================
+
+# Grid output options (output is always active)
+ out_file_name = LaPalma_test # output file name
+ out_pvd = 1 # activate writing .pvd file
+ out_phase = 1
+ out_density = 1
+ out_visc_total = 1
+ out_visc_creep = 1
+ out_visc_plast = 1
+ out_velocity = 1
+ out_pressure = 1
+ out_over_press = 1
+ out_litho_press = 1
+ out_temperature = 1
+# out_dev_stress = 1
+ out_j2_dev_stress = 1
+# out_strain_rate = 1
+ out_j2_strain_rate = 1
+ out_plast_strain = 1
+ out_plast_dissip = 1
+ out_tot_displ = 1
+ out_moment_res = 1
+ out_cont_res = 1
+ out_yield = 1
+
+# AVD phase viewer output options (requires activation)
+ out_avd = 1 # activate AVD phase output
+ out_avd_pvd = 1 # activate writing .pvd file
+ out_avd_ref = 1 # AVD grid refinement factor
+
+# free surface output
+ out_surf = 1 # activate surface output
+ out_surf_pvd = 1 # activate writing .pvd file
+ out_surf_velocity = 1
+ out_surf_topography = 1
+ out_surf_amplitude = 1
+
+
+#===============================================================================
+# ............................ Material Parameters .............................
+#===============================================================================
+
+# ------------------- Air -------------------
+
+ Name = air
+ ID = 0
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Water -------------------
+
+ Name = water
+ ID = 1
+ rho = 100
+ alpha = 3e-5
+
+ # Linear Viscosity
+ eta = 1e17
+
+ # Elastic parameters
+ G = 1e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 30
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+# ------------------- Upper Crust -------------------
+
+ Name = Crust
+ ID = 2
+ rho = 2900
+ alpha = 3e-5
+
+ # dislocation viscosity
+ #disl_prof = Plagioclase_An75-Ranalli_1995
+ #disl_prof = Wet_Quarzite-Ranalli_1995
+ disl_prof = Mafic_Granulite-Ranalli_1995
+
+
+ # Elastic parameters
+ G = 3e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+
+
+# ------------------- Mantle lithosphere-------------------
+
+ Name = Mantle
+ ID = 3
+ rho = 3320
+ alpha = 3e-5
+
+ # dislocation viscosity
+ disl_prof = Dry_Olivine-Ranalli_1995
+
+ # Elastic parameters
+ G = 6.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3.3
+ Cp = 1000
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Andesite -------------------
+
+ Name = magma
+ ID = 4
+ rho = 2700
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e18
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 980
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+
+# ------------------- Dacite -------------------
+
+ ID = 5
+ rho = 2575
+ alpha = 3e-5
+
+ # linear viscosity
+ eta = 1e19
+
+ # Elastic parameters
+ G = 1.5e10
+ nu = 0.2
+
+ # Thermal parameters
+ k = 3
+ Cp = 1000
+ T = 800
+
+ # Plastic parameters
+ ch = 10e6
+ fr = 30
+
+# End of defining material properties for all phases ----------------------------------------
+
+
+#===============================================================================
+# PETSc options
+#===============================================================================
+
+
+# SNES
+
+ -snes_npicard 5
+ -snes_max_it 200
+ -snes_rtol 1e-6
+ -snes_atol 1e-6
+ -snes_PicardSwitchToNewton_rtol 1e-7 #-7
+ #-snes_NewtonSwitchToPicard_it 1 # number of Newton iterations after which we switch back to Picard
+# -snes_monitor
+# -snes_linesearch_monitor
+
+# Jacobian solver
+ -js_ksp_type fgmres
+ -js_ksp_monitor
+ -js_ksp_max_it 30
+ -js_ksp_rtol 1e-5
+ -js_ksp_atol 1e-6
+# -js_ksp_monitor_true_residual
+
+# -its_ksp_monitor
+# -ts_ksp_monitor
+
+# Multigrid
+ -gmg_pc_mg_galerkin
+ -gmg_pc_mg_type multiplicative
+ -gmg_pc_mg_cycle_type v
+
+ -gmg_mg_levels_ksp_type richardson
+ -gmg_mg_levels_ksp_richardson_scale 0.5
+ -gmg_mg_levels_ksp_max_it 5
+ -gmg_mg_levels_pc_type jacobi
+
+ -crs_pc_factor_mat_solver_package pastix
+
+
+
+
+
+
+
diff --git a/v0.4.8/scripts/LaPalma_example.jl b/v0.4.8/scripts/LaPalma_example.jl
new file mode 100644
index 00000000..e1575367
--- /dev/null
+++ b/v0.4.8/scripts/LaPalma_example.jl
@@ -0,0 +1,125 @@
+# # Create a 3D LaMEM setup for La Palma
+#
+# ## Aim
+# In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021.
+# LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from `GeoData` to `CartData`.
+#
+#
+# ## 1. Load data
+# We will use two types of data to create the model
+# 1) Topography
+# 2) Earthquake locations
+
+# We start with loading the required packages
+using GeophysicalModelGenerator, JLD2
+using GMT
+
+# In case you managed to install GMT on your machine, you can automatically download the topography with
+Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file="@earth_relief_03s.grd")
+
+# In case you did not manage that, we have prepared a JLD2 file [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1).
+# Download it, and doublecheck that you are in the same directory as the data file with:
+pwd()
+
+# Load the data:
+Topo=load("Topo_LaPalma.jld2","Topo")
+
+# Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from [https://www.ign.es/web/ign/portal/vlc-catalogo](https://www.ign.es/web/ign/portal/vlc-catalogo)).
+# Download that [here](https://seafile.rlp.net/f/03286a46a9f040a69b0f/?dl=1)
+data_all_EQ = load("EQ_Data.jld2","data_all_EQ")
+
+# Write the data to paraview with
+Write_Paraview(data_all_EQ,"data_all_EQ",PointsData=true)
+Write_Paraview(Topo,"Topo")
+
+# As earthquakes are point-wise data, you have to specify this.
+# ![LaPalma_EQTopo_GeoData](../assets/img/TopoEQs_LaPalma_GeoData.png)
+# Note that this data is not in "easy" coordinates (see coordinate axis in the plot, where `z` is *not* pointing upwards).
+
+# ## 2. Convert data
+# In order to create model setups, it is helpful to first transfer the data to Cartesian.
+# This requires us to first determine a *projection point*, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:
+proj = ProjectionPoint(Lon=-17.84, Lat=28.56)
+
+# Once this is done you can convert the topographic data to the cartesian reference frame
+EQ_cart = Convert2CartData(data_all_EQ, proj);
+Topo_cart = Convert2CartData(Topo, proj)
+
+# It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small.
+# In other cases, however, this is quite substantial (e.g., India-Asia collision zone).
+# LaMEM needs an orthogonal grid of topography, which we can create with:
+Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));
+
+# In a next step, the routine `ProjectCartData` projects a `GeoData` structure to a `CartData` struct
+Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)
+
+# Let's have a look at the data:
+Write_Paraview(EQ_cart,"EQ_cart",PointsData=true)
+Write_Paraview(Topo_LaMEM,"Topo_LaMEM")
+
+# ## 3. Create LaMEM setup
+#
+# In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and
+# the number of control volumes (elements), you want to apply in every direction.
+# The LaMEM input file can be downloaded [here](../scripts/LaPalma.dat).
+# Make sure you are in the same directory as the *.dat file & execute the following command
+Grid = ReadLaMEM_InputFile("LaPalma.dat")
+
+# The `LaMEM_grid` structure contains the number of elements in every direction and the number of markers in every cell.
+# It also contains `Grid.X`, `Grid.Y`, `Grid.Z`, which are the coordinates of each of the markers in the 3 directions.
+#
+# In a next step we need to give each of these points a `Phase` number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).
+Phases = ones(Int32,size(Grid.X))*2;
+Temp = ones(Float64,size(Grid.X));
+
+# In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers
+Geotherm = 30;
+Temp = -Grid.Z.*Geotherm;
+
+# Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)
+Temp[Temp.<20] .= 20;
+Temp[Temp.>1350] .= 1350;
+
+# Because of lacking data, we have pretty much no idea where the Moho is in La Palma.
+# Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to "mantle":
+ind = findall( Grid.Z .< -40);
+Phases[ind] .= 3;
+
+# Everything above the free surface is assumed to be "air"
+ind = AboveSurface(Grid, Topo_cart);
+Phases[ind] .= 0;
+
+# And all "air" points that are below sea-level becomes "water"
+ind = findall( (Phases.==0) .& (Grid.Z .< 0));
+Phases[ind] .= 1;
+
+# You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small).
+# If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses.
+# We will assume the second option in our model setup.
+#
+# Looking at the seismicity, there is a swarm at around 35 km depth
+AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# A shallower one exists as well
+AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# And there might be a mid-crustal one
+AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));
+
+# We can generate a 3D model setup, which must include the `Phases` and `Temp` arrays
+Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))
+Write_Paraview(Model3D,"Model3D")
+
+# The model setup looks like this
+# ![LaMEM_ModelSetup_LaPalma](../assets/img/LaMEM_ModelSetup_LaPalma.png)
+
+# We can create a LaMEM marker file from the `Model3D` setup and the (cartesian) topography
+Save_LaMEMTopography(Topo_cart, "Topography.txt")
+Save_LaMEMMarkersParallel(Model3D)
+
+# Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well.
+# If you are interested in doing this, have a look at the LaMEM [wiki](https://bitbucket.org/bkaus/lamem/wiki/Home) pages.
+
+
+#src Note: The markdown page is generated using:
+#src Literate.markdown("LaPalma_example.jl",outputdir="../man/", execute=true)
\ No newline at end of file
diff --git a/v0.4.8/scripts/Tutorial_Votemaps.jl b/v0.4.8/scripts/Tutorial_Votemaps.jl
new file mode 100644
index 00000000..597f26cc
--- /dev/null
+++ b/v0.4.8/scripts/Tutorial_Votemaps.jl
@@ -0,0 +1,77 @@
+# # Votemaps
+#
+# ## Aim
+# In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.
+#
+# ## Steps
+#
+# #### 1. Load data
+# We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to
+# [https://seafile.rlp.net/d/22b0fb85550240758552/](https://seafile.rlp.net/d/22b0fb85550240758552/)
+#
+# Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form
+# Download the corresponding *.jld2 files to the same directory
+using JLD2, GeophysicalModelGenerator
+
+Pwave_Zhao = load("Zhao_Pwave.jld2","Data_set_Zhao2016_Vp")
+PSwave_Koulakov = load("Koulakov_Europe.jld2","DataKoulakov_Alps")
+Pwave_Paffrath = load("Paffrath_Pwave.jld2","Data_set_Paffrath2021_Vp")
+
+# The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:
+Pwave_Paffrath
+GeoData
+ size : (162, 130, 42)
+ lon ϵ [ -13.3019 : 35.3019]
+ lat ϵ [ 30.7638 : 61.2362]
+ depth ϵ [ -606.0385 km : 31.0385 km]
+ fields: (:dVp_Percentage, :Vp, :Resolution)
+
+PSwave_Koulakov
+ GeoData
+ size : (108, 81, 35)
+ lon ϵ [ 4.0 : 20.049999999999997]
+ lat ϵ [ 37.035928143712574 : 49.01197604790419]
+ depth ϵ [ -700.0 km : -10.0 km]
+ fields: (:dVp_percentage, :dVs_percentage)
+
+# #### 2. Creating a Votemap
+# The idea of `Votemaps` is rather simple:
+# - assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)
+# - Everything that fulfills this criteria gets the number 1, everything else 0.
+# - Do the same with other tomographic models (using the same criteria or a different one).
+# - Make sure that all tomographic models are interpolated to the same grid.
+# - Sum up the 3 models.
+# - The resulting 3D map will have the number `3` at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.
+#
+# The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)
+#
+# So how do we create Votemaps?
+# Doing this is rather simple:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_percentage>2.0","dVp_Percentage>2.0"], dims=(100,100,100))
+
+# This will look at the common `lon`,`lat`,`depth` ranges between all 3 models, interpret each of the models to a common grid of size `(100,100,100)` and apply each of the criteria specified
+# The resulting `GeoData` struct looks like:
+GeoData
+ size : (100, 100, 100)
+ lon ϵ [ 4.0 : 18.0]
+ lat ϵ [ 38.0 : 49.01197604790419]
+ depth ϵ [ -606.0385 km : -10.0 km]
+ fields: (:VoteMap,)
+
+# And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.
+Write_Paraview(Data_VoteMap, "VoteMap_Alps")
+
+# In paraview, this gives
+# ![Tutorial_VoteMap](../assets/img/Tutorial_VoteMap.png)
+
+# You can ofcourse argue that newer tomographic models include more data & should therefore count more
+# A simple way to take that into account is to list the model twice:
+Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],
+ ["dVp_Percentage>3.0","dVp_Percentage>3.0", "dVp_percentage>2.0","dVp_Percentage>2.0"],
+ dims=(100,100,100))
+
+# Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)
+
+
+
diff --git a/v0.4.8/search/index.html b/v0.4.8/search/index.html
new file mode 100644
index 00000000..6aae999d
--- /dev/null
+++ b/v0.4.8/search/index.html
@@ -0,0 +1,2 @@
+
+Search · GeophysicalModelGenerator.jl
Loading search...
Settings
This document was generated with Documenter.jl on Monday 17 April 2023. Using Julia version 1.7.3.
diff --git a/v0.4.8/search_index.js b/v0.4.8/search_index.js
new file mode 100644
index 00000000..4a6f826a
--- /dev/null
+++ b/v0.4.8/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"man/dataimport/#Data-importing","page":"Data Import","title":"Data importing","text":"","category":"section"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"We have a number of ways to import data, besides using any of the additional packages in julia to read files.","category":"page"},{"location":"man/dataimport/","page":"Data Import","title":"Data Import","text":"GeophysicalModelGenerator.Screenshot_To_GeoData\nGeophysicalModelGenerator.Screenshot_To_CartData\nGeophysicalModelGenerator.Screenshot_To_UTMData","category":"page"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_GeoData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_GeoData","text":"Screenshot_To_GeoData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, Cartesian=false, UTM=false, UTMzone, isnorth=true)\n\nTake a screenshot of Georeferenced image either a lat/lon, x,y (if Cartesian=true) or in UTM coordinates (if UTM=true) at a given depth or along profile and converts it to a GeoData, CartData or UTMData struct, which can be saved to Paraview\n\nThe lower left and upper right coordinates of the image need to be specified in tuples of (lon,lat,depth) or (UTM_ew, UTM_ns, depth), where depth is negative in the Earth (and in km).\n\nThe lower right and upper left corners can be specified optionally (to take non-orthogonal images into account). If they are not specified, the image is considered orthogonal and the corners are computed from the other two.\n\nNote: if your data is in UTM coordinates you also need to provide the UTMzone and whether we are on the northern hemisphere or not (isnorth).\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_CartData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_CartData","text":"Data = Screenshot_To_CartData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing)\n\nDoes the same as Screenshot_To_GeoData, but returns a CartData structure\n\n\n\n\n\n","category":"function"},{"location":"man/dataimport/#GeophysicalModelGenerator.Screenshot_To_UTMData","page":"Data Import","title":"GeophysicalModelGenerator.Screenshot_To_UTMData","text":"Data = Screenshot_To_UTMData(filename::String, Corner_LowerLeft, Corner_UpperRight; Corner_LowerRight=nothing, Corner_UpperLeft=nothing, UTMzone::Int64=nothing, isnorth::Bool=true)\n\nDoes the same as Screenshot_To_GeoData, but returns for UTM data Note that you have to specify the UTMzone and isnorth\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_loadirregular3DSeismicData/#D-tomography-model-that-is-re-interpolated-on-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3D tomography model that is re-interpolated on a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#Goal","page":"Interpolate irregular 3D seismic tomography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"This explains how to load a 3D seismic data set that is given in CSV format (comma separated ASCII), and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"As the data is not given in a regular lon/lat grid, we first interpolate it to a different mesh.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#Steps","page":"Interpolate irregular 3D seismic tomography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Download-data","page":"Interpolate irregular 3D seismic tomography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is can be downloaded from https://www.seismologie.ifg.uni-kiel.de/en/research/research-data/mere2020model. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Read-data-into-Julia","page":"Interpolate irregular 3D seismic tomography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The main data-file, El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv, has 23 lines of comments (indicated with #), after which the data starts. We can use the build-in package DelimitedFiles to read in the data, and tell it that the data is seperated by |. We also want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"El-Sharkawy-etal-G3.2020_MeRE2020_Mediterranean.csv\",'|',Float64,'\\n', skipstart=23,header=false)\n3695678×4 Matrix{Float64}:\n 32.12 -11.0 50.0 4.57\n 36.36 -11.0 50.0 4.47\n 38.32 -10.99 50.0 4.4\n 49.77 -10.99 50.0 4.52\n 29.82 -10.98 50.0 4.44\n 34.1 -10.98 50.0 4.56\n 40.26 -10.98 50.0 4.36\n 42.19 -10.97 50.0 4.38\n 44.1 -10.97 50.0 4.38\n ⋮ ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> lat = data[:,1];\njulia> lon = data[:,2];\njulia> depth=-data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we put a minus sign in front of depth, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Reformat-the-data","page":"Interpolate irregular 3D seismic tomography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/#.1-Load-and-plot-the-data-layout","page":"Interpolate irregular 3D seismic tomography","title":"3.1 Load and plot the data layout","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The data is now available as a bunch of data points. In principle we can plot that in Paraview, but it is better to reformat it into a 3D grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Let's first have a look at how the data is distributed at a given depth level. For that, extract all points at 50 km depth and plot it (make sure you have the Plots.l package installed)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ind=findall(x -> x==-50.0, depth)\njulia> using Plots\njulia> scatter(lon[ind],lat[ind],marker_z=Vs[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The result looks like this:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"So this is somewhat regular but not entirely and in some areas data points are missing. It is possible to create a VTK mesh that exactly respects this data, but for that we need knowledge on how the points are connected in 3D. The comments in the file do not provide this information, which is why we interpolate it on a regular lon/lat grid here which uses the same depth levels as in the data.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We extract the available depth levels with ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Depth_vec = unique(depth)\n301-element Vector{Float64}:\n -50.0\n -51.0\n -52.0\n -53.0\n -54.0\n -55.0\n -56.0\n ⋮\n -345.0\n -346.0\n -347.0\n -348.0\n -349.0\n -350.0","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"which shows that the data set goes from [-350:1:-50]. Let's create a regular grid, which describes a somewhat smaller area than the data-points to ensure that we can do an interpolation without having to extrapolate","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator \njulia> Lon,Lat,Depth = LonLatDepthGrid(-10:0.5:40,32:0.25:50,Depth_vec);\njulia> size(Lon)\n(101, 73, 301)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The last command shows the size of our new grid.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We can plot our new Lon/Lat grid on top of the previous data:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> scatter!(Lon[:,:,1],Lat[:,:,1],color=:white, markersize=1.5, markertype=\"+\",legend=:none)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.2-Interpolate-to-a-regular-grid","page":"Interpolate irregular 3D seismic tomography","title":"3.2 Interpolate to a regular grid","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Next, we need a method to interpolate the irregular datapoints @ a certain depth level to the white data points. ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"There are a number of ways to do this, for example by employing GMT.jl, or by using GeoStats.jl. In this example, we will employ GeoStats. If you haven't installed it yet, do that with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> ]\n(@v1.6) pkg> add GeoStats","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"We will first show how to interpolate data @ 50 km depth.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeoStats\njulia> Cgrid = CartesianGrid((size(Lon,1),size(Lon,2)),(minimum(Lon),minimum(Lat)),(Lon[2,2,2]-Lon[1,1,1],Lat[2,2,2]-Lat[1,1,1]))\n101×73 CartesianGrid{2,Float64}\n minimum: Point(-10.0, 32.0)\n maximum: Point(40.5, 50.25)\n spacing: (0.5, 0.25)\njulia> coord = PointSet([lon[ind]'; lat[ind]'])\n12278 PointSet{2,Float64}\n └─Point(-11.0, 32.12)\n └─Point(-11.0, 36.36)\n └─Point(-10.99, 38.32)\n └─Point(-10.99, 49.77)\n └─Point(-10.98, 29.82)\n ⋮\n └─Point(45.97, 42.91)\n └─Point(45.98, 37.22)\n └─Point(45.99, 42.07)\n └─Point(45.99, 46.76)\n └─Point(45.99, 50.52)\njulia> Geo = georef((Vs=Vs[ind],), coord)\n12278 MeshData{2,Float64}\n variables (rank 0)\n └─Vs (Float64)\n domain: 12278 PointSet{2,Float64}\njulia> P = EstimationProblem(Geo, Cgrid, :Vs)\n2D EstimationProblem\n data: 12278 MeshData{2,Float64}\n domain: 101×73 CartesianGrid{2,Float64}\n variables: Vs (Float64)\njulia> S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \njulia> sol = solve(P, S)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Here, we interpolated the data based on the Euclidean distance. Other methods, such as Kriging, can be used as well. Next, we can extract the data","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> sol_Vs = values(sol).Vs\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)))\njulia> heatmap(Lon[:,1,1],Lat[1,:,1],Vs_2D', clims=(3.9, 4.8))","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_interpolated)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The final step is to repeat this procedure for all depth levels:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> Vs_3D = zeros(size(Depth));\njulia> for iz=1:size(Depth,3)\n println(\"Depth = $(Depth[1,1,iz])\")\n ind = findall(x -> x==Depth[1,1,iz], depth)\n coord = PointSet([lon[ind]'; lat[ind]'])\n Geo = georef((Vs=Vs[ind],), coord)\n P = EstimationProblem(Geo, Cgrid, :Vs)\n S = IDW(:Vs => (distance=Euclidean(),neighbors=2)); \n sol = solve(P, S)\n sol_Vs= values(sol).Vs\n Vs_2D = reshape(sol_Vs, size(domain(sol)))\n Vs_3D[:,:,iz] = Vs_2D;\n end","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Generate-Paraview-file","page":"Interpolate irregular 3D seismic tomography","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Once the 3D velocity matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (101, 73, 301)\n lon ϵ [ -10.0 - 40.0]\n lat ϵ [ 32.0 - 50.0]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Plotting-data-in-Paraview","page":"Interpolate irregular 3D seismic tomography","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/#.-Julia-script","page":"Interpolate irregular 3D seismic tomography","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadirregular3DSeismicData/","page":"Interpolate irregular 3D seismic tomography","title":"Interpolate irregular 3D seismic tomography","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/tutorials/#Tutorials","page":"Overview","title":"Tutorials","text":"","category":"section"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"The best way to learn how to use julia and GeophysicalModelGenerator to visualize your data is to look at the tutorials.","category":"page"},{"location":"man/tutorials/","page":"Overview","title":"Overview","text":"3D seismic tomography data on regular grid. Demonstrates how to load 3D data that are defined on a regular longitude/latitude/depth grid.\nMoho topography data. Shows how to plot Moho data as 3D points in paraview, and how to fit a surface through it.\nTopography. Shows how to quickly obtain the topography of any part of the world using GMT & transfer that to paraview.\nCoastlines. Shows how to generate land/sea surfaces.\nImport screenshots. Gives examples how you can easily import screenshots from published papers and visualize them in 3D \n3D seismic tomography data on irregular grid. Shows how to interpolate 3D seismic data, given on an irregular lon/lat grid, to a regular grid and create Paraview input from it.\nTopography and geological maps. Shows how to import ETOPO1 topography, how to drape a geological map over it & transfer that to Paraview.\nISC earthquake data. Shows how to import earthquake data from the ISC catalogue.\nPlot GPS data. Shows how to load and plot GPS data as vectors.","category":"page"},{"location":"man/tutorial_local_Flegrei/#Km-scale-volcano-tutorial-using-cartesian-coordinates","page":"Kilometer-scale volcano","title":"Km-scale volcano tutorial using cartesian coordinates","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#Goal","page":"Kilometer-scale volcano","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This tutorial visualizes available 3D data at a local volcano (Campi Flegrei caldera, Italy) using cartesian coordinates. This is done, e.g., when we only have geomorphological data in cartesian coordinates. It includes geological and geophysical data in UTM format from the following papers:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Two shape files containing coastline and faults:\nVilardo, G., Ventura, G., Bellucci Sessa, E. and Terranova, C., 2013. Morphometry of the Campi Flegrei caldera (southern Italy). Journal of maps, 9(4), pp.635-640. doi:10.1080/17445647.2013.842508\nEarthquake data for two volcanic unrests, in 1983-84 and 2005-2016:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7\nDe Siena, L., Sammarco, C., Cornwell, D.G., La Rocca, M., Bianco, F., Zaccarelli, L. and Nakahara, H., 2018. Ambient seismic noise image of the structurally controlled heat and fluid feeder pathway at Campi Flegrei caldera. Geophysical Research Letters, 45(13), pp.6428-6436. doi:10.1029/2018GL078817\nTravel time tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x\nAmbient noise tomography model:\nBattaglia, Jean, Aldo Zollo, Jean Virieux, and Dario Dello Iacono, 2008. Merging active and passive data sets in traveltime tomography: the case study of Campi Flegrei caldera (Southern Italy). Geophysical Prospecting 56, no. 4: 555-573. doi:10.1111/j.1365-2478.2007.00687.x","category":"page"},{"location":"man/tutorial_local_Flegrei/#Steps","page":"Kilometer-scale volcano","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/#.-Download-all-data-for-region","page":"Kilometer-scale volcano","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Make sure that you are in the unzipped directory.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Geomorphology","page":"Kilometer-scale volcano","title":"2. Geomorphology","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Load both the the shape (.shp) files contained in \"./Geomorphology/*.shp\" inside Paraview. In the following figures we show the Cartesian representation (not geolocalized - left) and the UTM (UTM). Our shape files can only be loaded in the cartesian:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Geomorphology)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"To reproduce it, represent the coastline as data points with black solid color and assign your favourite color map to the morphology. Note that each block color number corresponds to a different morphology. Beware that this file only works in cartesian coordinate, as it is still impossible to generate shape files in real UTM coordinates","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Earthquakes","page":"Kilometer-scale volcano","title":"3. Earthquakes","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Now let's plot earthquake data provided as text files. Start loading the data contained in \"./SeismicLocations/*.txt\". The first column gives us a temporal marker we can use to plot earthquakes in different periods.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Glob, GeoStats\njulia> data_80s = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> data_00s = readdlm(\"SeismicLocations/Seismicity_UTM_2005_2016.txt\", ' ', skipstart=0, header=false);\njulia> data = vcat(data_80s,data_00s) \njulia> time = data[:,1];\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> EQ_Data_Cart = CartData(WE,SN,depth,(Depth=depth * m,Time=time * yr,));\njulia> Write_Paraview(EQ_Data_Cart, \"CF_Earthquakes_Cartesian\", PointsData=true)\njulia> EQ_Data_UTM = UTMData(WE, SN, depth, 33, true, (Depth=depth * m,Time=time * yr,));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,EQ_Data_UTM)\njulia> Write_Paraview(Data_set_UTM, \"CF_Earthquakes_UTM\", PointsData=true)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Save in paraview with both cartesian and UTM formats. The final seismicity map looks like this:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_seismicity)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"The colour scale distinguishes earthquakes of different decades. Notice the progressive migration of recent seismicity (black dots) towards East.","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Velocity-model","page":"Kilometer-scale volcano","title":"4. Velocity model","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using the Alps tutorial it is easy to create a paraview file from the Vp, Vs and Vp/Vs model in \"./TravelTmeTomography/modvPS.dat\" for both cartesian and UTM coordinates.","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data = readdlm(\"TravelTimeTomography/modvPS.dat\", '\\t', Float64, skipstart=0, header=false);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vp = data[:,4];\njulia> Vs = data[:,5];\njulia> VpVs = data[:,6];\njulia> resolution = (length(unique(depth)), length(unique(SN)), length(unique(WE)))\njulia> dim_perm = [3 2 1]\njulia> we = permutedims(reshape(WE, resolution), dim_perm);\njulia> sn = permutedims(reshape(SN, resolution), dim_perm);\njulia> depth = permutedims(reshape(depth, resolution), dim_perm);\njulia> Vp3d = permutedims(reshape(Vp, resolution), dim_perm);\njulia> Vs3d = permutedims(reshape(Vs, resolution), dim_perm);\njulia> Vp_Vs3d = permutedims(reshape(VpVs, resolution), dim_perm);\njulia> Data_set_Cartesian = CartData(we, sn, depth, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Write_Paraview(Data_set_Cartesian, \"CF_Velocity_Cartesian\")\njulia> Data_set = UTMData(we, sn, depth, 33, true, (vp = Vp3d * (km / s), vs = Vs3d * (km / s), vpvs = Vp_Vs3d,))\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData,Data_set)\njulia> Write_Paraview(Data_set_UTM, \"CF_Velocity_UTM\")","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Including the Vp/Vs model in the previous Paraview file workspace:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_VpVs)","category":"page"},{"location":"man/tutorial_local_Flegrei/#.-Horizontal-slices-of-shear-velocity-on-irregular-grid","page":"Kilometer-scale volcano","title":"5. Horizontal slices of shear velocity on irregular grid","text":"","category":"section"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Using ambient noise you can map shear wave velocity at different depths. The models at each depth are contained in the files \"./NoiseTomography/*.txt\". We read them consecutively in a \"for\" loop:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> list_files = glob(\"AmbientNoiseTomography/*.txt\");\njulia> li = size(list_files, 1);\njulia> for i = 1:li\njulia> nameFile = list_files[i];\njulia> name_vts = name_vts[24:26];\njulia> data = readdlm(nameFile, '\\t', Float64);\njulia> WE = data[:,1];\njulia> SN = data[:,2];\njulia> depth = data[:,3];\njulia> Vs = data[:,4];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"However these models are too wide, so it is better to constrain them:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> findall( (WE .>= 419000) .& (WE.<=435000) .& (SN.>=4514000) .& (SN.<=4528000) );\njulia> WE = WE[ind];\njulia> SN = SN[ind];\njulia> depth = depth[ind];\njulia> Vs = Vs[ind];","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"Also, nodes are irregular, hence we create a 3D regular UTM:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"julia> l = length(WE);\njulia> n_WE = minimum(WE):100:maximum(WE);\njulia> n_SN = minimum(SN):100:maximum(SN);\njulia> we, sn, Depth = XYZGrid(n_WE, n_SN, depth[1]);\njulia> Vs_3D = zeros(size(Depth));\njulia> Cgrid = GeoStats.CartesianGrid((size(we, 1), size(we, 2)), (minimum(we), minimum(sn)), (we[2,2,1] - we[1,1,1], sn[2,2,1] - sn[1,1,1]))\njulia> coord = PointSet([WE[:]'; SN[:]']);\njulia> Geo = georef((Vs = Vs[:],), coord);\njulia> P = EstimationProblem(Geo, Cgrid, :Vs);\njulia> S = IDW(:Vs => (;neighbors=2));\njulia> sol = solve(P, S);\njulia> sol_Vs = values(sol).Vs;\njulia> Vs_2D = reshape(sol_Vs, size(domain(sol)));\njulia> Vs_3D[:,:,1] = Vs_2D;\njulia> Data_set_Cart = CartData(we, sn, Depth, (Vs = Vs_3D * (km / s),))\njulia> Write_Paraview(Data_set_Cart, \"CF_Noise\" * name_vts * \"_Cartesian\")\njulia> Data_set = UTMData(we, sn, Depth, 33, true, (Vs = Vs_3D*(km / s),));\njulia> Data_set_UTM = convert(GeophysicalModelGenerator.GeoData, Data_set);\njulia> Write_Paraview(Data_set_UTM, \"CF_Noise_UTM_\"*name_vts)\njulia> end","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"This is one of the horizontal sections created by the code in the previous model in both reference systems:","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"(Image: Tutorial_Flegrei_Noise)","category":"page"},{"location":"man/tutorial_local_Flegrei/","page":"Kilometer-scale volcano","title":"Kilometer-scale volcano","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"We have a number of functions with which we can extract sub-data from a 2D or 3D GeoData structure.","category":"page"},{"location":"man/tools/","page":"Tools","title":"Tools","text":"GeophysicalModelGenerator.CrossSection\nGeophysicalModelGenerator.ExtractSubvolume\nGeophysicalModelGenerator.InterpolateDataFields\nGeophysicalModelGenerator.VoteMap\nGeophysicalModelGenerator.SubtractHorizontalMean\nGeophysicalModelGenerator.AboveSurface\nGeophysicalModelGenerator.BelowSurface\nGeophysicalModelGenerator.InterpolateDataOnSurface\nGeophysicalModelGenerator.ParseColumns_CSV_File\nGeophysicalModelGenerator.RotateTranslateScale!\nGeophysicalModelGenerator.Convert2UTMzone\nGeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ImportTopo\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.DrapeOnTopo\nGeophysicalModelGenerator.LithostaticPressure!","category":"page"},{"location":"man/tools/#GeophysicalModelGenerator.CrossSection","page":"Tools","title":"GeophysicalModelGenerator.CrossSection","text":"CrossSection(DataSet::GeoData; dims=(100,100), Interpolate=false, Depth_level=nothing; Lat_level=nothing; Lon_level=nothing; Start=nothing, End=nothing )\n\nCreates a cross-section through a GeoData object. \n\nCross-sections can be horizontal (map view at a given depth), if Depth_level is specified\nThey can also be vertical, either by specifying Lon_level or Lat_level (for a fixed lon/lat), or by defining both Start=(lon,lat) & End=(lon,lat) points.\nDepending on the type of input data (volume, surface or point data), cross sections will be created in a different manner:\n\nVolume data: data will be interpolated or directly extracted from the data set.\nSurface data: surface data will be interpolated or directly extracted from the data set\nPoint data: data will be projected to the chosen profile. Only data within a chosen distance (default is 50 km) will be used\n\nInterpolate indicates whether we want to simply extract the data from the data set (default) or whether we want to linearly interpolate it on a new grid, which has dimensions as specified in dims NOTE: THIS ONLY APPLIES TO VOLUMETRIC aND SURFACE DATA SETS\n'section_width' indicates the maximal distance within which point data will be projected to the profile\n\nExample:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz))); \njulia> Data_cross = CrossSection(Data_set3D, Depth_level=-100km) \nGeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -100.0 km : -100.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ExtractSubvolume","page":"Tools","title":"GeophysicalModelGenerator.ExtractSubvolume","text":"ExtractSubvolume(V::GeoData; Interpolate=false, Lon_level=nothing, Lat_level=nothing, Depth_level=nothing, dims=(50,50,50))\n\nExtract or \"cuts-out\" a piece of a 2D or 3D GeoData set, defined by Lon, Lat and Depth coordinates.\n\nThis is useful if you are only interested in a part of a much bigger larger data set.\n\nLon_level,Lat_level and Depth_level should be tuples that indicate (minimum_value, maximum_value) along the respective direction. If not specified we use the full range. \nBy default, Interpolate=false and we find the closest indices within the data set (so your new data set will not go exactly from minimum to maximum).\nAlternatively, if Interpolate=true we interpolate the data onto a new grid that has dimensions dims. This can be useful to compare data sets that are originally given in different resolutions.\n\n3D Example with no interpolation:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; # some data\njulia> Vx,Vy,Vz = ustrip(Data*3),ustrip(Data*4),ustrip(Data*5);\njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon, Velocity=(Vx,Vy,Vz)))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40))\nGeoData \n size : (3, 6, 13)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\nBy default it extracts the data points closest to the area defined by Lonlevel/Latlevel/Depth_level.\n\n3D Example with interpolation:\n\nAlternatively, you can also interpolate the data onto a new grid:\n\njulia> Data_extracted = ExtractSubvolume(Data_set3D,Lon_level=(10,12),Lat_level=(35,40), Interpolate=true, dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 10.0 : 12.0]\n lat ϵ [ 35.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData, :Velocity)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataFields","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataFields","text":"InterpolateDataFields(V::AbstractGeneralGrid, Lon, Lat, Depth)\n\nInterpolates a data field V on a grid defined by Lon,Lat,Depth\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set1= CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData \n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n \njulia> X,Y,Z = XYZGrid(0:4:10, -1:.1:1, -5:.1:1 );\njulia> Data_set2= InterpolateDataFields(Data_set1, X,Y,Z)\n\n\n\n\n\nInterpolateDataFields(V::UTMData, EW, NS, Depth)\n\nInterpolates a data field V on a grid defined by UTM,Depth\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.VoteMap","page":"Tools","title":"GeophysicalModelGenerator.VoteMap","text":"VoteMap(DataSets::Vector{GeoData}, criteria::Vector{String}, dims=(50,50,50))\n\nCreates a Vote map which shows consistent features in different 2D/3D tomographic datasets.\n\nThe way it works is:\n\nFind a common region between the different GeoData sets (overlapping lon/lat/depth regions)\nInterpolate the fields of all DataSets to common coordinates\nFilter data points in one model (e.g., areas with a velocity anomaly > 2 percent). Set everything that satisfies this criteria to 1 and everything else to 0.\nSum the results of the different datasets\n\nIf a feature is consistent between different datasets, it will have larger values. \n\nExample\n\nWe assume that we have 2 seismic velocity datasets Data_Zhao_Pwave and DataKoulakov_Alps:\n\njulia> Data_Zhao_Pwave\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> DataKoulakov_Alps\n GeoData \n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)\n\nYou can create a VoteMap which combines the two data sets with:\n\njulia> Data_VoteMap = VoteMap([Data_Zhao_Pwave,DataKoulakov_Alps],[\"dVp_Percentage>2.5\",\"dVp_percentage>3.0\"])\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:VoteMap,)\n\nYou can also create a VoteMap of a single dataset:\n\njulia> Data_VoteMap = VoteMap(Data_Zhao_Pwave,\"dVp_Percentage>2.5\", dims=(50,51,52))\nGeoData \n size : (50, 51, 52)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:VoteMap,)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.SubtractHorizontalMean","page":"Tools","title":"GeophysicalModelGenerator.SubtractHorizontalMean","text":"V_sub = SubtractHorizontalMean(V::AbstractArray{T, 3}; Percentage=false)\n\nSubtracts the horizontal average of the 3D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\nV_sub = SubtractHorizontalMean(V::AbstractArray{T, 2}; Percentage=false)\n\nSubtracts the horizontal average of the 2D data array V.\n\nIf Percentage=true, the result is given as percentage; otherwise absolute values are returned\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.AboveSurface","page":"Tools","title":"GeophysicalModelGenerator.AboveSurface","text":"AboveSurface(Data::GeoData, DataSurface::GeoData; above=true)\n\nReturns a boolean array of size(Data.Lon), which is true for points that are above the surface DataSurface (or for points below if above=false).\n\nThis can be used, for example, to mask points above/below the Moho in a volumetric dataset or in a profile.\n\nExample\n\nFirst we create a 3D data set and a 2D surface:\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data = Depth*2; \njulia> Data_set3D = GeoData(Lon,Lat,Depth,(Depthdata=Data,LonData=Lon))\nGeoData \n size : (11, 11, 13)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -300.0 km : 0.0 km]\n fields: (:Depthdata, :LonData)\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-40km); \njulia> Data_Moho = GeoData(Lon,Lat,Depth+Lon*km, (MohoDepth=Depth,))\n GeoData \n size : (11, 11, 1)\n lon ϵ [ 10.0 : 20.0]\n lat ϵ [ 30.0 : 40.0]\n depth ϵ [ -30.0 km : -20.0 km]\n fields: (:MohoDepth,)\n\nNext, we intersect the surface with the data set:\n\njulia> Above = AboveSurface(Data_set3D, Data_Moho); \n\nNow, Above is a boolean array that is true for points above the surface and false for points below and at the surface.\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_Cart::CartData, DataSurface_Cart::CartData; above=true)\n\nDetermines if points within the 3D Data_Cart structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Grid::CartGrid, DataSurface_Cart::CartData; above=true)\n\nDetermines if points described by the Grid CartGrid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\nAbove = AboveSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are above the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.BelowSurface","page":"Tools","title":"GeophysicalModelGenerator.BelowSurface","text":"Below = BelowSurface(Data::GeoData, DataSurface::GeoData)\n\nDetermines if points within the 3D Data structure are below the GeoData surface DataSurface\n\n\n\n\n\nBelow = BelowSurface(Grid::CartGrid, DataSurface_Cart::CartData)\n\nDetermines if points described by the `Grid` CartGrid structure are above the Cartesian surface `DataSurface_Cart`\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::ParaviewData, DataSurface_Cart::ParaviewData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_Cart::CartData, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D DataCart structure are below the Cartesian surface DataSurfaceCart\n\n\n\n\n\nBelow = BelowSurface(Data_LaMEM::LaMEM_grid, DataSurface_Cart::CartData)\n\nDetermines if points within the 3D LaMEM_grid structure are below the Cartesian surface DataSurface_Cart\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.InterpolateDataOnSurface","page":"Tools","title":"GeophysicalModelGenerator.InterpolateDataOnSurface","text":"Surf_interp = InterpolateDataOnSurface(V::ParaviewData, Surf::ParaviewData)\n\nInterpolates a 3D data set V on a surface defined by Surf. nex\n\nExample\n\njulia> Data\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\njulia> surf\nParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:Depth,)\njulia> Surf_interp = InterpolateDataOnSurface(Data, surf)\n ParaviewData \n size : (96, 96, 1)\n x ϵ [ -2.9671875 : 3.2671875]\n y ϵ [ -1.9791666666666667 : 1.9791666666666667]\n z ϵ [ -1.5353766679763794 : -0.69925457239151]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\nSurf_interp = InterpolateDataOnSurface(V::GeoData, Surf::GeoData)\n\nInterpolates a 3D data set V on a surface defined by Surf\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.ParseColumns_CSV_File","page":"Tools","title":"GeophysicalModelGenerator.ParseColumns_CSV_File","text":"ParseColumns_CSV_File(data_file, num_columns)\n\nThis parses numbers from CSV file that is read in with CSV.File. That is useful in case the CSV files has tables that contain both strings (e.g., station names) and numbers (lat/lon/height) and you are only intested in the numbers\n\nExample\n\nThis example assumes that the data starts at line 18, that the colums are separated by spaces, and that it contains at most 4 columns with data:\n\njulia> using CSV\njulia> data_file = CSV.File(\"FileName.txt\",datarow=18,header=false,delim=' ')\njulia> data = ParseColumns_CSV_File(data_file, 4)\n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.DrapeOnTopo","page":"Tools","title":"GeophysicalModelGenerator.DrapeOnTopo","text":"Topo = DrapeOnTopo(Topo::GeoData, Data::GeoData)\n\nThis drapes fields of a data set Data on the topography Topo \n\n\n\n\n\nDrapeOnTopo(Topo::CartData, Data::CartData)\n\nDrapes Cartesian Data on topography \n\n\n\n\n\n","category":"function"},{"location":"man/tools/#GeophysicalModelGenerator.LithostaticPressure!","page":"Tools","title":"GeophysicalModelGenerator.LithostaticPressure!","text":"LithostaticPressure!(Plithos::Array, Density::Array, dz::Number; g=9.81)\n\nComputes lithostatic pressure from a 3D density array, assuming constant soacing dz in vertical direction. Optionally, the gravitational acceleration g can be specified.\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_MohoTopo/#Moho-topography","page":"Visualize Moho topography","title":"Moho topography","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#Goal","page":"Visualize Moho topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"This explains how to load the Moho topography for Italy and the Alps and create a paraview file ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Spada, M., Bianchi, I., Kissling, E., Agostinetti, N.P., Wiemer, S., 2013. Combining controlled-source seismology and receiver function information to derive 3-D Moho topography for Italy. Geophysical Journal International 194, 1050–1068. doi:10.1093/gji/ggt148","category":"page"},{"location":"man/tutorial_MohoTopo/#Steps","page":"Visualize Moho topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/#.-Download-data","page":"Visualize Moho topography","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data is available as digital dataset on the researchgate page of Prof. Edi Kissling https://www.researchgate.net/publication/322682919MohoMap_Data-WesternAlps-SpadaETAL2013","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"We have also uploaded it here: https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full data set actually includes 3 different Moho's (Europe, Adria, Tyrrhenia-Corsica). To simplify matters, we have split the full file into 3 seperate ascii files and uploaded it.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Please download the files Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt, Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt and Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Read-data-into-Julia","page":"Visualize Moho topography","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The data sets start at line 39. We read this into julia as:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using DelimitedFiles\njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho1.txt\",' ',Float64,'\\n', skipstart=38,header=false)\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Note that depth is made negative.","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Reformat-the-data","page":"Visualize Moho topography","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using Plots\njulia> scatter(lon,lat,marker_z=depth, ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"What we can see nicely here is that the data is reasonably regular but also that there are obviously locations where no data is define.","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The easiest way to transfer this to Paraview is to simply save this as 3D data points:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using GeophysicalModelGenerator\njulia> data_Moho1 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\nGeoData \n size : (12355,)\n lon ϵ [ 4.00026 - 11.99991]\n lat ϵ [ 42.51778 - 48.99544]\n depth ϵ [ -57.46 km - -21.34 km]\n fields: (:MohoDepth,)\njulia> Write_Paraview(data_Moho1, \"Spada_Moho_Europe\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we can do the same with the other two Moho's:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho2.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho2 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho2, \"Spada_Moho_Adria\", PointsData=true) \njulia> data =readdlm(\"Moho_Map_Data-WesternAlps-SpadaETAL2013_Moho3.txt\",' ',Float64,'\\n', skipstart=38,header=false);\njulia> lon, lat, depth = data[:,1], data[:,2], -data[:,3];\njulia> data_Moho3 = GeoData(lon,lat,depth,(MohoDepth=depth*km,))\njulia> Write_Paraview(data_Moho3, \"Spada_Moho_Tyrrhenia\", PointsData=true) ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"If we plot this in paraview, it looks like this: (Image: DataPoints_PV)","category":"page"},{"location":"man/tutorial_MohoTopo/#.1-Fitting-a-mesh-through-the-data","page":"Visualize Moho topography","title":"3.1 Fitting a mesh through the data","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"So obviously, the Moho is discontinuous between these three Mohos. Often, it looks nicer if we fit a regular surface through these data points. To do this we first combine the data points of the 3 surfaces into one set of points ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> lon = [data_Moho1.lon.val; data_Moho2.lon.val; data_Moho3.lon.val];\njulia> lat = [data_Moho1.lat.val; data_Moho2.lat.val; data_Moho3.lat.val];\njulia> depth = [data_Moho1.depth.val; data_Moho2.depth.val; data_Moho3.depth.val];\njulia> data_Moho_combined = GeoData(lon, lat, depth, (MohoDepth=depth*km,))","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Next, we define a regular lon/lat grid ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(4.1:0.1:11.9,42.5:.1:49,-30km);","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"And we will use a nearest neighbor interpolation method to fit a surface through the data. This has the advantage that it will take the discontinuities into account. We will use the package NearestNeighbors.jl for this, which you may have to install first ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> using NearestNeighbors\njulia> kdtree = KDTree([lon'; lat'])\njulia> idxs, dists = knn(kdtree, [Lon[:]'; Lat[:]'], 1, true)","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"idxs contains the indices of the closest points to the grid in (Lon,Lat). Next ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> Depth = zeros(size(Lon))*km;\njulia> for i=1:length(idxs)\n Depth[i] = depth[idxs[i]][1]\n end","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"Now, we can create a GeoData structure with the regular surface and save it to paraview:","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> data_Moho = GeoData(Lon, Lat, Depth, (MohoDepth=Depth,))\njulia> Write_Paraview(data_Moho, \"Spada_Moho_combined\") ","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The result is shown here, where the previous points are colored white and are a bit smaller. Obviously, the datasets coincide well. (Image: DataPoints_Moho_surface)","category":"page"},{"location":"man/tutorial_MohoTopo/#.-Julia-script","page":"Visualize Moho topography","title":"4. Julia script","text":"","category":"section"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_MohoTopo/","page":"Visualize Moho topography","title":"Visualize Moho topography","text":"julia> include(\"MohoTopo_Spada.jl\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Extract-ETOPO1-topographic-data-using-GMT.jl-and-drape-a-geological-map-on-top-of-the-topography-(given-as-raster-graphics)","page":"ETOPO1 Topography and geological maps","title":"Extract ETOPO1 topographic data using GMT.jl and drape a geological map on top of the topography (given as raster graphics)","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Goal","page":"ETOPO1 Topography and geological maps","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In many cases, we want to add topographic data as well a information about tectonic units to our visualization. This tutorial shows how to use GMT.jl to import data from an ETOPO1 file for a certain region, load a geological map from a raster graphics file (here: PNG), drape it over the topography and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#Steps","page":"ETOPO1 Topography and geological maps","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Download-topographic-data-and-tectonic-maps-of-the-Alpine-region","page":"ETOPO1 Topography and geological maps","title":"1. Download topographic data and tectonic maps of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The ETOPO1 data file used in this example can be downloaded here: https://ngdc.noaa.gov/mgg/global/global.html. For this example we downloaded ETOPO1Iceg_gmt4.grd and stored it directly in the folder where we will be working. For the geological map, we download the data from the SPP 4DMB repository and extract the zip file (also in the current folder). In this data set, a gmt file with the data for different tectonic units is given in ./ tectonicmaps4dmb20200917/GMTexample/alcapadi_polygons.gmt . ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Create-a-tectonic-map-with-orthogonal-projection","page":"ETOPO1 Topography and geological maps","title":"2. Create a tectonic map with orthogonal projection","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"To create a png with an orthogonal map projection (which we need for the png import), we do the following in julia: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> \njulia> using GMT\njulia> filename_gmt = \"./tectonic_maps_4dmb_2020_09_17/GMT_example/alcapadi_polygons.gmt\"\njulia> plot(filename_gmt,region=\"4/20/37/49\",show=true)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"This opens a window with the plotted map. Save this image in your current working folder. Open it with a image manipulation of your choice (e.g. GIMP) and crop it to the map itself. Save the cropped image in your current working directory. For this tutorial, we have named the cropped png file tectonicmap_SPP.png. It looks like this:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap_PNG)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Import-data-to-paraview","page":"ETOPO1 Topography and geological maps","title":"3. Import data to paraview","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Now, to import the ETOPO1 topography data and to drape the geologic map over it, open julia again. Load the following packages:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> using GMT, NearestNeighbors, GeoParams, GeophysicalModelGenerator","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"First, define the filenames of the files you want to import: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> filename_topo = \"./ETOPO1/ETOPO1_Ice_g_gmt4.grd\" \njulia> filename_geo = \"./tectonicmap_SPP.png\"","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Next, define the region that you want to visualize (note that we use the same coordinates here as we used previously for the generation of the geological map): ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> lat_min = 37.0\njulia> lat_max = 49.0\njulia> lon_min = 4.0\njulia> lon_max = 20.0","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the data","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> G = gmtread(filename_topo, limits=[lon_min,lon_max,lat_min,lat_max], grid=true);\nLon,Lat,Depth = LonLatDepthGrid(G.x[1:end],G.y[1:end],0);\nnumel_topo = prod(size(Lon));\nDepth[:,:,1] = 1e-3*G.z';\nDataTopo = GeophysicalModelGenerator.GeoData(Lon, Lat, Depth, (Topography=Depth*km,))","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"At this step, only the topographic data is imported. Now we have to import the tectonic map from the png file. To do so, first define the longitude and latitude of the lower left and upper right corner of the png (as we create:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Corner_LowerLeft = ( lon_min, lat_min , 0.0)\njulia> Corner_UpperRight = (lon_max, lat_max , 0.0)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"and import the png file with the GMG function ScreenshotToGeoData: ","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> DataPNG = Screenshot_To_GeoData(filename_geo, Corner_LowerLeft, Corner_UpperRight)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The tricky part is then to interpolate the colors from the geological map to the topography. Here, we simply use nearesat neighbor interpolation (NearestNeighbors.jl) to do so. First, we have to set up the KDTree and determine the nearest neighbors of the points in our Lat/Lon grid","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> coord = [vec(DataPNG.lon.val)';vec(DataPNG.lat.val)'];\njulia> kdtree = KDTree(coord; leafsize = 10);\njulia> points = [vec(Lon)';vec(Lat)'];\njulia> dx,dist = nn(kdtree, points);","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Once this is done, the respective colors have to be assigned to a field in the DataTopo structure:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> red = zeros(size(Depth));\njulia> green = zeros(size(Depth));\njulia> blue = zeros(size(Depth));\njulia> tmp = DataPNG.fields.colors[1];\njulia> red[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[2];\njulia> green[1:numel_topo] = tmp[idx];\njulia> tmp = DataPNG.fields.colors[3];\njulia> blue[1:numel_topo] = tmp[idx];","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Finally, to avoid artefacts, all colors outside the region described by the tectonic map are set to white:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> ind_tmp = Lat .< Corner_LowerLeft[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lat .> Corner_UpperRight[2];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .< Corner_LowerLeft[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;\n\njulia> ind_tmp = Lon .> Corner_UpperRight[1];\njulia> red[ind_tmp] .= 1;\njulia> green[ind_tmp] .= 1;\njulia> blue[ind_tmp] .= 1;","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/#.-Save","page":"ETOPO1 Topography and geological maps","title":"4. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"Transforming the to Paraview is now a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"julia> Data_set = GeoData(Lon, Lat, Depth, (Topography=Depth*km,colors=(red,green,blue)))\njulia> Write_Paraview(Data_set, \"test_GeoMap\")","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"The result is shown here:","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"(Image: Tutorial_GMT_topography_GeologicalMap)","category":"page"},{"location":"man/tutorial_GMT_Topography_GeologicalMap/","page":"ETOPO1 Topography and geological maps","title":"ETOPO1 Topography and geological maps","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#D-tomography-model-in-CSV-formation","page":"3D seismic tomography from ASCII","title":"3D tomography model in CSV formation","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#Goal","page":"3D seismic tomography from ASCII","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This explains how to load a 3D P-wave model and plot it in Paraview as a 3D volumetric data set. It also shows how you can create horizontal or vertical cross-sections through the data in a straightforward manner and how you can extract subsets of the data; The example is the P-wave velocity model of the Alps as described in: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Zhao, L., Paul, A., Malusà, M.G., Xu, X., Zheng, T., Solarino, S., Guillot, S., Schwartz, S., Dumont, T., Salimbeni, S., Aubert, C., Pondrelli, S., Wang, Q., Zhu, R., 2016. Continuity of the Alpine slab unraveled by high-resolution P wave tomography. Journal of Geophysical Research: Solid Earth 121, 8720–8737. doi:10.1002/2016JB013310","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is given in ASCII format with longitude/latitude/depth/velocity anomaly (percentage) format.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Steps","page":"3D seismic tomography from ASCII","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/#.-Download-data","page":"3D seismic tomography from ASCII","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The data is can be downloaded from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/, where you should download the file Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Read-data-into-Julia","page":"3D seismic tomography from ASCII","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The dataset has no comments, and the data values in every row are separated by a space. In order to read this into julia as a matrix, we can use the build-in julia package DelimitedFiles. We want the resulting data to be stored as double precision values (Float64), and the end of every line is a linebreak (\\n).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using DelimitedFiles\njulia> data=readdlm(\"Zhao_etal_JGR_2016_Pwave_Alps_3D_k60.txt\",' ',Float64,'\\n', skipstart=0,header=false)\n1148774×4 Matrix{Float64}:\n 0.0 38.0 -1001.0 -0.113\n 0.15 38.0 -1001.0 -0.081\n 0.3 38.0 -1001.0 -0.069\n 0.45 38.0 -1001.0 -0.059\n 0.6 38.0 -1001.0 -0.055\n 0.75 38.0 -1001.0 -0.057\n ⋮ \n 17.25 51.95 -1.0 -0.01\n 17.4 51.95 -1.0 -0.005\n 17.55 51.95 -1.0 0.003\n 17.7 51.95 -1.0 0.007\n 17.85 51.95 -1.0 0.006\n 18.0 51.95 -1.0 0.003","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, extract vectors from it:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> lon = data[:,1];\njulia> lat = data[:,2];\njulia> depth = data[:,3];\njulia> dVp_perc = data[:,4];","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that depth needs to with negative numbers.","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Reformat-the-data","page":"3D seismic tomography from ASCII","title":"3. Reformat the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Let's first have a look at the depth range of the data set:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Depth_vec = unique(depth)\n101-element Vector{Float64}:\n -1001.0\n -991.0\n -981.0\n -971.0\n -961.0\n -951.0\n ⋮\n -51.0\n -41.0\n -31.0\n -21.0\n -11.0\n -1.0","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So the data has a vertical spacing of 10 km. Next, let's check if the data is spaced in a regular manner in Lon/Lat direction. For that, we read the data at a given depth level (say -101km) and plot it using the Plots package (you may have to install that first on your machine).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using Plots\njulia> ind=findall(x -> x==-101.0, depth)\njulia> scatter(lon[ind],lat[ind],marker_z=dVp_perc[ind], ylabel=\"latitude\",xlabel=\"longitude\",markersize=2.5, c = :roma)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Note that we employ the scientific colormap roma here. This gives an overview of available colormaps. You can download the colormaps for Paraview here. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Clearly, the data is given as regular Lat/Lon points:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> unique(lon[ind])\n121-element Vector{Float64}:\n 0.0\n 0.15\n 0.3\n 0.45\n 0.6\n 0.75\n ⋮\n 17.25\n 17.4\n 17.55\n 17.7\n 17.85\n 18.0\njulia> unique(lat[ind])\n94-element Vector{Float64}:\n 38.0\n 38.15\n 38.3\n 38.45\n 38.6\n 38.75\n ⋮\n 51.2\n 51.35\n 51.5\n 51.65\n 51.8\n 51.95","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.1-Reshape-data-and-save-to-paraview","page":"3D seismic tomography from ASCII","title":"3.1 Reshape data and save to paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next, we reshape the vectors with lon/lat/depth data into 3D matrixes:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> resolution = (length(unique(lon)), length(unique(lat)), length(unique(depth)))\n(121, 94, 101)\njulia> Lon = reshape(lon, resolution);\njulia> Lat = reshape(lat, resolution);\njulia> Depth = reshape(depth, resolution);\njulia> dVp_perc_3D = reshape(dVp_perc, resolution);","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Check that the results are consistent","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> iz=findall(x -> x==-101.0, Depth[1,1,:])\n1-element Vector{Int64}:\n 91\njulia> data=dVp_perc_3D[:,:,iz];\njulia> heatmap(unique(lon), unique(lat),data[:,:,1]', c=:roma,title=\"$(Depth[1,1,iz]) km\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: DataPoints)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"So this looks good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Next we create a paraview file:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(dVp_Percentage=dVp_perc_3D,))\nGeoData \n size : (121, 94, 101)\n lon ϵ [ 0.0 - 18.0]\n lat ϵ [ 38.0 - 51.95]\n depth ϵ [ -1001.0 km - -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_set, \"Zhao_etal_2016_dVp_percentage\")\n1-element Vector{String}:\n \"Zhao_etal_2016_dVp_percentage.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from ASCII","title":"4. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In paraview you should open the *.vts file, and press Apply (left menu) after doing that. Once you did that you can select dVp_Percentage and Surface (see red ellipses below)/. In paraview you can open the file and visualize it. ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_1)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This visualisation employs the default colormap, which is not particularly good.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"You can change that by importing the roma colormap (using the link described earlier). For this, open the colormap editor and click the one with the heart on the right hand side. Next, import roma and select it.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_2)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In order to change the colorrange select the button in the red ellipse and change the lower/upper bound. (Image: Paraview_3)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to create a horizontal cross-section @ 200 km depth, you need to select the Slice tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_4)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"After pushing Apply, you'll see this:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_5)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you want to plot iso-surfaces (e.g. at -3%), you can use the Clip option again, but this time select scalar and don't forget to unclick invert.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_6)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-and-plot-cross-sections-of-the-data","page":"3D seismic tomography from ASCII","title":"5. Extract and plot cross-sections of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"In many cases you would like to create cross-sections through the 3D data sets as well, and visualize that in Paraview. That is in principle possible in Paraview as well (using the Slice tool, as described above). Yet, in many cases we want to have it at a specific depth, or through pre-defined lon/lat coordinates.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"There is a simple way to achieve this using the CrossSection function. To make a cross-section at a given depth:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Depth_level=-100km) \nGeoData \n size : (121, 94, 1)\n lon ϵ [ 0.0 : 18.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -101.0 km : -101.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_100km\")\n1-element Vector{String}:\n \"Zhao_CrossSection_100km.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Or at a specific longitude:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10)\nGeoData \n size : (1, 94, 101)\n lon ϵ [ 10.05 : 10.05]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,) \njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10\")\n1-element Vector{String}:\n \"Zhao_CrossSection_Lon10.vts\"","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"As you see, this cross-section is not taken at exactly 10 degrees longitude. That is because by default we don't interpolate the data, but rather use the closest point in longitude in the original data set.","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you wish to interpolate the data, specify Interpolate=true:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Lon_level=10, Interpolate=true)\nGeoData \n size : (1, 100, 100)\n lon ϵ [ 10.0 : 10.0]\n lat ϵ [ 38.0 : 51.95]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_Lon10_interpolated\");","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"as you see, this causes the data to be interpolated on a (100,100) grid (which can be changed by adding a dims input parameter).","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"We can also create a diagonal cut through the model:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_cross = CrossSection(Data_set, Start=(1.0,39), End=(18,50))\nGeoData \n size : (100, 100, 1)\n lon ϵ [ 1.0 : 18.0]\n lat ϵ [ 39.0 : 50.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_cross, \"Zhao_CrossSection_diagonal\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Here an image that shows the resulting cross-sections: ","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"(Image: Paraview_7)","category":"page"},{"location":"man/tutorial_load3DSeismicData/#.-Extract-a-(3D)-subset-of-the-data","page":"3D seismic tomography from ASCII","title":"6. Extract a (3D) subset of the data","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"Sometimes, the data set covers a large region (e.g., the whole Earth), and you are only interested in a subset of this data for your project. You can obviously cut your data to the correct size in Paraview. Yet, an even easier way is the routine ExtractSubvolume:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45))\nGeoData \n size : (48, 35, 101)\n lon ϵ [ 4.95 : 12.0]\n lat ϵ [ 39.95 : 45.05]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"This gives the resulting image. You can obviously use that new, smaller, data set to create cross-sections etc. (Image: Paraview_8)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"By default, we extract the original data and do not interpolate it on a new grid. In some cases, you will want to interpolate the data on a different grid. Use the Interpolate=true option for that:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> Data_subset_interp = ExtractSubvolume(Data_set,Lon_level=(5,12), Lat_level=(40,45), Interpolate=true)\nGeoData \n size : (50, 50, 50)\n lon ϵ [ 5.0 : 12.0]\n lat ϵ [ 40.0 : 45.0]\n depth ϵ [ -1001.0 km : -1.0 km]\n fields: (:dVp_Percentage,)\njulia> Write_Paraview(Data_subset, \"Zhao_Subset_interp\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Load-and-save-data-to-disk","page":"3D seismic tomography from ASCII","title":"Load and save data to disk","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"It would be useful to save the 3D data set we just created to disk, such that we can easily load it again at a later stage and create cross-sections etc, or compare it with other models. It is quite easy to do so with the JLD2.jl package:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2\njulia> jldsave(\"Zhao_Pwave.jld2\"; Data_set)","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"If you, at a later stage, want to load this file again do it as follows:","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> using JLD2, GeophysicalModelGenerator\njulia> Data_set_Zhao2016_Vp = load_object(\"Zhao_Pwave.jld2\")","category":"page"},{"location":"man/tutorial_load3DSeismicData/#Julia-script","page":"3D seismic tomography from ASCII","title":"Julia script","text":"","category":"section"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_load3DSeismicData/","page":"3D seismic tomography from ASCII","title":"3D seismic tomography from ASCII","text":"julia> include(\"Alps_VpModel_Zhao_etal_JGR2016.jl\")","category":"page"},{"location":"man/datastructures/#Data-structures","page":"Data Structures","title":"Data structures","text":"","category":"section"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"The main data structure used in GeophysicalModelGenerator.jl is GeoData, which contains info about the longitude,latitude, and depth of a data set, as well as several data sets itself. We also provide a UTMData, which is essentially the same but with UTM coordinates, and a CartData structure, which has Cartesian coordinates in kilometers (as used in many geodynamic codes). If one wishes to transfer GeoData to CartData, one needs to provide a ProjectionPoint. For plotting, we transfer this into the ParaviewData structure, which has cartesian coordinates around the center of the Earth. We employ the wgs84 reference ellipsoid as provided by the Geodesy.jl package to perform this transformation.","category":"page"},{"location":"man/datastructures/","page":"Data Structures","title":"Data Structures","text":"GeophysicalModelGenerator.GeoData\nGeophysicalModelGenerator.UTMData\nGeophysicalModelGenerator.ParaviewData\nGeophysicalModelGenerator.CartData\nGeophysicalModelGenerator.LonLatDepthGrid\nGeophysicalModelGenerator.XYZGrid\nGeophysicalModelGenerator.ProjectionPoint","category":"page"},{"location":"man/datastructures/#GeophysicalModelGenerator.GeoData","page":"Data Structures","title":"GeophysicalModelGenerator.GeoData","text":"GeoData(lon::Any, lat:Any, depth::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with longitude, latitude and depth information.\n\ndepth can have units of meter, kilometer or be unitless; it will be converted to km.\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well. lon,lat,depth should all have the same size as each of the fields.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> Lat = 1.0:3:10.0;\njulia> Lon = 11.0:4:20.0;\njulia> Depth = (-20:5:-10)*km;\njulia> Lon3D,Lat3D,Depth3D = LonLatDepthGrid(Lon, Lat, Depth);\njulia> Lon3D\n3×4×3 Array{Float64, 3}:\n[:, :, 1] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 2] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\n\n[:, :, 3] =\n 11.0 11.0 11.0 11.0\n 15.0 15.0 15.0 15.0\n 19.0 19.0 19.0 19.0\njulia> Lat3D\n 3×4×3 Array{Float64, 3}:\n [:, :, 1] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 2] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n \n [:, :, 3] =\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\n 1.0 4.0 7.0 10.0\njulia> Depth3D\n 3×4×3 Array{Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 3}:\n [:, :, 1] =\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n -20.0 km -20.0 km -20.0 km -20.0 km\n \n [:, :, 2] =\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n -15.0 km -15.0 km -15.0 km -15.0 km\n \n [:, :, 3] =\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\n -10.0 km -10.0 km -10.0 km -10.0 km\njulia> Data = zeros(size(Lon3D));\njulia> Data_set = GeophysicalModelGenerator.GeoData(Lon3D,Lat3D,Depth3D,(DataFieldName=Data,)) \nGeoData \n size : (3, 4, 3)\n lon ϵ [ 11.0 : 19.0]\n lat ϵ [ 1.0 : 10.0]\n depth ϵ [ -20.0 km : -10.0 km]\n fields : (:DataFieldName,)\n attributes: [\"note\"]\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.UTMData","page":"Data Structures","title":"GeophysicalModelGenerator.UTMData","text":"UTMData(EW::Any, NS:Any, depth::GeoUnit, UTMZone::Int, NorthernHemisphere=true, fields::NamedTuple)\n\nData structure that holds one or several fields with UTM coordinates (east-west), (north-south) and depth information.\n\ndepth can have units of meters, kilometer or be unitless; it will be converted to meters (as UTMZ is usually in meters)\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Veast,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nLat,Lon,Depth should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to lon, second dimension to lat and third dimension to depth (which should be in km). See below for an example.\n\nExample\n\njulia> ew = 422123.0:100:433623.0\njulia> ns = 4.514137e6:100:4.523637e6\njulia> depth = -5400:250:600\njulia> EW,NS,Depth = XYZGrid(ew, ns, depth);\njulia> Data = ustrip.(Depth);\njulia> Data_set = UTMData(EW,NS,Depth,33, true, (FakeData=Data,Data2=Data.+1.)) \nUTMData \n UTM zone : 33-33 North\n size : (116, 96, 25)\n EW ϵ [ 422123.0 : 433623.0]\n NS ϵ [ 4.514137e6 : 4.523637e6]\n depth ϵ [ -5400.0 m : 600.0 m]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nIf you wish, you can convert this from UTMData to GeoData with\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nwhich would allow visualizing this in paraview in the usual manner:\n\njulia> Write_Paraview(Data_set1, \"Data_set1\")\n1-element Vector{String}:\n \"Data_set1.vts\"\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.ParaviewData","page":"Data Structures","title":"GeophysicalModelGenerator.ParaviewData","text":"ParaviewData(x::GeoUnit, y::GeoUnit, z::GeoUnit, values::NamedTuple)\n\nCartesian data in x/y/z coordinates to be used with Paraview. This is usually generated automatically from the GeoData structure, but you can also invoke do this manually:\n\njulia> Data_set = GeophysicalModelGenerator.GeoData(1.0:10.0,11.0:20.0,(-20:-11)*km,(DataFieldName=(-20:-11),)) \njulia> Data_cart = convert(ParaviewData, Data_set)\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.CartData","page":"Data Structures","title":"GeophysicalModelGenerator.CartData","text":"CartData(x::Any, y::Any, z::GeoUnit, fields::NamedTuple)\n\nData structure that holds one or several fields with with Cartesian x/y/z coordinates. Distances are in kilometers\n\nx,y,z can have units of meters, kilometer or be unitless; they will be converted to kilometers\nfields should ideally be a NamedTuple which allows you to specify the names of each of the fields. \nIn case you only pass one array we will convert it to a NamedTuple with default name.\nA single field should be added as (DataFieldName=Data,) (don't forget the comma at the end).\nMultiple fields can be added as well.\nIn case you want to display a vector field in paraview, add it as a tuple: (Velocity=(Vx,Vnorth,Vup), Veast=Veast, Vnorth=Vnorth, Vup=Vup); we automatically apply a vector transformation when transforming this to a ParaviewData structure from which we generate Paraview output. As this changes the magnitude of the arrows, you will no longer see the [Veast,Vnorth,Vup] components in Paraview which is why it is a good ideas to store them as separate Fields.\nYet, there is one exception: if the name of the 3-component field is colors, we do not apply this vector transformation as this field is regarded to contain RGB colors. \nx,y,z should have the same size as the Data array. The ordering of the arrays is important. If they are 3D arrays, as in the example below, we assume that the first dimension corresponds to x, second dimension to y and third dimension to z (which should be in km). See below for an example.\n\nExample\n\njulia> x = 0:2:10\njulia> y = -5:5\njulia> z = -10:2:2\njulia> X,Y,Z = XYZGrid(x, y, z);\njulia> Data = Z\njulia> Data_set = CartData(X,Y,Z, (FakeData=Data,Data2=Data.+1.))\nCartData \n size : (6, 11, 7)\n x ϵ [ 0.0 km : 10.0 km]\n y ϵ [ -5.0 km : 5.0 km]\n z ϵ [ -10.0 km : 2.0 km]\n fields : (:FakeData, :Data2)\n attributes: [\"note\"]\n\nCartData is particularly useful in combination with cartesian geodynamic codes, such as LaMEM, which require cartesian grids. You can directly save your data to Paraview with\n\njulia> Write_Paraview(Data_set, \"Data_set\")\n1-element Vector{String}:\n \"Data_set.vts\"\n\nIf you wish, you can convert this to UTMData (which will simply convert the )\n\njulia> Data_set1 = convert(GeoData, Data_set)\nGeoData \n size : (116, 96, 25)\n lon ϵ [ 14.075969111533457 : 14.213417764154963]\n lat ϵ [ 40.77452227533946 : 40.86110443583479]\n depth ϵ [ -5.4 km : 0.6 km]\n fields: (:FakeData, :Data2)\n\nwhich would allow visualizing this in paraview in the usual manner:\n\n\n\n\n\n","category":"type"},{"location":"man/datastructures/#GeophysicalModelGenerator.LonLatDepthGrid","page":"Data Structures","title":"GeophysicalModelGenerator.LonLatDepthGrid","text":"Lon, Lat, Depth = LonLatDepthGrid(Lon::Any, Lat::Any, Depth:Any)\n\nCreates 3D arrays of Lon, Lat, Depth from 1D vectors or numbers\n\nExample 1: Create 3D grid\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-10:-1)km);\njulia> size(Lon)\n(11, 11, 10)\n\nExample 2: Create 2D lon/lat grid @ a given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,-50km);\njulia> size(Lon)\n(11, 11)\n\nExample 3: Create 2D lon/depth grid @ a given lat\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30,(-10:-1)km);\njulia> size(Lon)\n(11, 11)\n\nExample 4: Create 1D vertical line @ a given lon/lat point\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10,30,(-10:-1)km);\njulia> size(Lon)\n(10, )\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.XYZGrid","page":"Data Structures","title":"GeophysicalModelGenerator.XYZGrid","text":"X,Y,Z = XYZGrid(X_vec::Any, Y_vec::Any, Z_vec::Any)\n\nCreates a X,Y,Z grid. It works just as LonLatDepthGrid apart from the better suited name.\n\nExample 1: Create 3D grid\n\njulia> X,Y,Z = XYZGrid(10:20,30:40,(-10:-1)km);\njulia> size(X)\n(11, 11, 10)\n\nSee LonLatDepthGrid for more examples.\n\n\n\n\n\n","category":"function"},{"location":"man/datastructures/#GeophysicalModelGenerator.ProjectionPoint","page":"Data Structures","title":"GeophysicalModelGenerator.ProjectionPoint","text":"struct ProjectionPoint\n Lon :: Float64\n Lat :: Float64\n EW :: Float64\n NS :: Float64\n zone :: Integer\n isnorth :: Bool\nend\n\nStructure that holds the coordinates of a point that is used to project a data set from Lon/Lat to a Cartesian grid and vice-versa.\n\n\n\n\n\n","category":"type"},{"location":"man/tutorial_time_Seismicity/#How-to-create-a-movie-to-show-seismic-distribution-through-time","page":"Create movies","title":"How to create a movie to show seismic distribution through time","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#Goal","page":"Create movies","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial creates a movie of the spatial variations in seismicity using the earthquakes previously visualized at Campi Flegrei caldera. We visualize it against the travel-time model and tomography:","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Earthquake data for the 1983-84 unrest:\nDe Siena, L., Chiodini, G., Vilardo, G., Del Pezzo, E., Castellano, M., Colombelli, S., Tisato, N. and Ventura, G., 2017. Source and dynamics of a volcanic caldera unrest: Campi Flegrei, 1983–84. Scientific reports, 7(1), pp.1-13. doi:10.1038/s41598-017-08192-7","category":"page"},{"location":"man/tutorial_time_Seismicity/#Steps","page":"Create movies","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/#.-Download-all-data-for-region","page":"Create movies","title":"1. Download all data for region","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"You will need to download the zipped folder containing all files from here.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Make sure that you are in the unzipped directory. To reproduce exactly the figure, you will need the velocity model loaded in the km-scale volcano tutorial, here","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_1)","category":"page"},{"location":"man/tutorial_time_Seismicity/#.-Earthquakes-in-movie","page":"Create movies","title":"2. Earthquakes in movie","text":"","category":"section"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Create the folder TemporalSeismicity in the current folder and open the movie with the function Movie_Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> using DelimitedFiles, GeophysicalModelGenerator, Dates\njulia> p2 = @__FILE__;\njulia> p2last = findlast(\"/\",p2);\njulia> p3 = chop(p2,head=0,tail = length(p2)-p2last[1]+1);\njulia> output_path = string(p3,\"/\");\njulia> movie = Movie_Paraview(name=string(p3,\"/TemporalSeismicity\"), Initialize=true);\njulia> if isdir(string(p3,\"/TemporalSeismicity\"))==0\njulia> mkdir(string(p3,\"/TemporalSeismicity\"));\njulia> end\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Now let's load the earthquake data provided as text files. The first column gives us a temporal marker we can use to plot earthquakes in different periods. We used the Date package to transform this time into dates.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> data = readdlm(\"SeismicLocations/Seismicity_UTM_1983_1984.txt\", '\\t', skipstart=0, header=false);\njulia> l = length(data[:,1]);\njulia> dates = Date.(zeros(l,1))\njulia> for i = 1:l\njulia> df = DateFormat(\"yyyymmdd\");\njulia> t1 = string(\"19\",@sprintf(\"%5.o\", data[i,1]));\njulia> t2 = Date(t1[1:8],df);\njulia> dates[i,1] = t2;\njulia> end\njulia> WE = data[:,2];\njulia> SN = data[:,3];\njulia> depth = data[:,4];\njulia> dates_num = dates - dates[1];\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Select earthquakes every 50 days from the starting date (17/01/1983) and use them to create the frames for the video.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"julia> nt = 50;\njulia> dt = Dates.Day(nt);\njulia> t = minimum(dates):dt:maximum(dates);\njulia> for itime = 1:length(t)-1\njulia> name = string(p3,\"/TemporalSeismicity/\", string(itime));\njulia> tt=findall(x->(x>=t[itime]) & (x<=t[itime+1]),dates);\njulia> we = WE[tt];\njulia> sn = SN[tt];\njulia> Depth1 = depth[tt];\njulia> DN = dates_num[tt];\njulia> label_time = Dates.value(DN[end]);\njulia> if size(tt,1)>1\njulia> Data_set = UTMData(we, sn, Depth1, 33, true, (Depth=Depth1*km,Timedata=DN));\njulia> movie = Write_Paraview(Data_set, name,pvd=movie,time=label_time,PointsData=true);\njulia> end\njulia>end\njulia>Movie_Paraview(pvd=movie, Finalize=true)\n","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"This tutorial has created a new TemporalSeismicity.pvd that can be loaded in Paraview.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_PVD)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"Notice the animation panel, allowing you to run the video. You can select video speed by opening the Animation View under the View tab. Note that you can slow down the movie there if you need.","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"(Image: Tutorial_SeismicTime_Movie)","category":"page"},{"location":"man/tutorial_time_Seismicity/","page":"Create movies","title":"Create movies","text":"If you want to run the entire example, you can find the .jl code here","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#Import-profiles/maps-from-published-papers","page":"Import screenshots","title":"Import profiles/maps from published papers","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#Goal","page":"Import screenshots","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Ideally, all data should be availabe in digital format, after which you could use the tools described in the other tutorial to transform them into GeoData and export them to VTK. Yet, the reality is different and often data is not (yet) available, or papers are old and the authors can no longer be contacted.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For that reason, GeophysicalModelGenerator has tools that allow you to transfer a screenshot from any published paper into GeoData/Paraview and see it in 3D at the correct geographic location. This can be done for vertical profiles and for mapviews, which gives you a quick and easy way to see those papers in a new (3D) light.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Here, we explain how. ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Import profiles/maps from published papers\nGoal\nGeneral procedure\n1. Download data and crop images\n2. Read data of a cross-section & create VTS file\n3. Read data of a mapview & create *.vts file\n4. Using an automatic digitizer to pick points on map\n5. Creating a multiblock Paraview/*.vtm file\n6. Julia script","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#General-procedure","page":"Import screenshots","title":"General procedure","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Download-data-and-crop-images","page":"Import screenshots","title":"1. Download data and crop images","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this example, we use a well-known paper about the Alps which is now openly available:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Lippitsch, R., 2003. Upper mantle structure beneath the Alpine orogen from high-resolution teleseismic tomography. J. Geophys. Res. 108, 2376. https://doi.org/10.1029/2002JB002016","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Figure 12 contains a number of horizontal slices @ different depth, whereas Figure 13 contains 3 vertical profiles and a mapview that illustrates where the profile was taken. The first profile is shown here:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The first step is to crop the image such that we only see the profile itself:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-cross-section-and-create-VTS-file","page":"Import screenshots","title":"2. Read data of a cross-section & create VTS file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"We look at the bigger image and determine the lon,lat,depth coordinates of the lower left and upper right corners of this image. We estimate this to be (well, in fact, Mark Handy knew the exact coordinates, which contain a typo in the paper but are correct in her PhD thesis):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Corner_LowerLeft = ( 4.65, 45.73, -400.0)\njulia> Corner_UpperRight = (17.23, 43.80, 0.0)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once this is done, and we saved the picture under Lippitsch_Fig13a.png, you can transfer it into GeoData format with:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> using GeophysicalModelGenerator\njulia> data_profile1 = Screenshot_To_GeoData(\"Lippitsch_Fig13a.png\",Corner_LowerLeft, Corner_UpperRight)\nExtracting GeoData from: Lippitsch_Fig13a.png\n └ Corners: lon lat depth\n └ lower left = (4.65 , 45.73 , -400.0 )\n └ lower right = (17.23 , 43.8 , -400.0 )\n └ upper left = (4.65 , 45.73 , 0.0 )\n └ upper right = (17.23 , 43.8 , 0.0 )\nGeoData \n size : (325, 824, 1)\n lon ϵ [ 4.6499999999999995 : 17.230000000000004]\n lat ϵ [ 43.79999999999999 : 45.730000000000004]\n depth ϵ [ -400.00000000000006 km : 0.0 km]\n fields: (:colors,)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Finally, you save it in Paraview format as always:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> Write_Paraview(data_profile1, \"Lippitsch_Fig13a_profile\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"You can open this in paraview. Here, it is shown along with topographic data (made transparent):","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"(Image: Tutorial_ScreenShots_Lippitsch_1) Note that if you want to see the image with the original colors, you should unselect the Map Scalars option in the Properties tab (red ellipse).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Read-data-of-a-mapview-and-create-*.vts-file","page":"Import screenshots","title":"3. Read data of a mapview & create *.vts file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Creating a map follows the same procedure. The only difference is that maps are sometimes distorted which means that the axis are not necessarily orthogonal in lon/lat space. In that case, you need to specify all 4 corners. Internally, we linearly interpolate between those values.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"An example is given here, which uses the mapview of Fig. 13 of the same paper (@ 150 km depth): (Image: Fig13_mapview)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Corner_LowerLeft = ( 3.5, 43.0 , -150.0)\nCorner_UpperRight = (15.5, 50.0 , -150.0)\nCorner_LowerRight = (15.5, 43.0 , -150.0)\nCorner_UpperLeft = (3.5 , 50.0 , -150.0)\ndata_Fig13_map = Screenshot_To_GeoData(\"Fig13_mapview.png\",Corner_LowerLeft, Corner_UpperRight, Corner_LowerRight=Corner_LowerRight,Corner_UpperLeft=Corner_UpperLeft)\nWrite_Paraview(data_Fig13_map, \"Lippitsch_Fig13_mapview\") ","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once added to paraview (together with a few additional map views from the same paper): (Image: Tutorial_ScreenShots_Lippitsch_4)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Using-an-automatic-digitizer-to-pick-points-on-map","page":"Import screenshots","title":"4. Using an automatic digitizer to pick points on map","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Often, it is not straightforward to determine the begin/end points of a profile and have to guess that by looking at the mapview (which is inprecise). To help with that, you can digitize the map and use an automatic digitizer to pick points on the map.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"A great online tool to do exactly that can be found here: https://automeris.io/WebPlotDigitizer/","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For this, you need to create a screenshot that is slightly larger and includes the axis (or a scale bar). As an example, you can use the image Digitizer_1.png which you can download here https://github.com/JuliaGeodynamics/GeophysicalModelGenerator.jl/blob/main/docs/src/assets/img/Digitizer_1.png.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If import this in the online tool and indicate this to be a 2D (X-Y) Plot, it will ask us to pick 2 points on the X axis and 2 points on the Y axis: (Image: Digitizer_2)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Once the map is referenced accordingly, we can pick points (here for C' - C) and show the corresponding data values: (Image: Digitizer_3)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Which can again be used to set your profile.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Creating-a-multiblock-Paraview/*.vtm-file","page":"Import screenshots","title":"5. Creating a multiblock Paraview/*.vtm file","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"If you are importing a lot of cross-sections at the same time in Paraview, you end up having a lot of open profiles. For that reason it is possible to save a \"multi-block\" *.vtm file, which combines several files into one. The general approach is simple: open a multiblock file, and pass the filename to Write_Paraview. Once you are done, save it. An example showing you how this works is:","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> vtmfile = vtk_multiblock(\"Lippitsch_CrossSections\")\njulia> Write_Paraview(data_Fig12_90km, vtmfile) \njulia> Write_Paraview(data_Fig12_180km, vtmfile) \njulia> Write_Paraview(data_Fig12_300km, vtmfile) \njulia> Write_Paraview(data_Fig12_400km, vtmfile) \njulia> vtk_save(vtmfile)","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"Note that you have to create the cross-sections first (see the julia script below).","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/#.-Julia-script","page":"Import screenshots","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"For convenience we collected a few screenshots and uploaded it from https://seafile.rlp.net/d/a50881f45aa34cdeb3c0/.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"The full julia script that interprets all the figures is given here.","category":"page"},{"location":"man/tutorial_Screenshot_To_Paraview/","page":"Import screenshots","title":"Import screenshots","text":"julia> include(\"Lippitsch_Screenshots.jl\")","category":"page"},{"location":"man/listfunctions/#List-of-all-functions","page":"List of functions","title":"List of all functions","text":"","category":"section"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"This page details the some of the guidelines that should be followed when contributing to this package.","category":"page"},{"location":"man/listfunctions/","page":"List of functions","title":"List of functions","text":"","category":"page"},{"location":"man/tutorial_GPS/#Plot-GPS-data","page":"Plot GPS vectors","title":"Plot GPS data","text":"","category":"section"},{"location":"man/tutorial_GPS/#Goal","page":"Plot GPS vectors","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The aim of this tutorial is to show you how you can download and plot GPS data, which are vector data. The example is based on a paper by Sanchez et al. (2018) https://essd.copernicus.org/articles/10/1503/2018/#section7","category":"page"},{"location":"man/tutorial_GPS/#Steps","page":"Plot GPS vectors","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GPS/#.-Download-and-import-GPS-data:","page":"Plot GPS vectors","title":"1. Download and import GPS data:","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The data related to the paper can be downloaded from: https://doi.pangaea.de/10.1594/PANGAEA.886889 There you will find links to several data sets. Some are the data on the actual stations and some are interpolated data on a grid. Here, we will use the gridded data as an example (which interpolates the ), and will therefore download the following data sets:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"ALPS2017DEFHZ\tSurface deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_HZ.GRD\nALPS2017DEFVT\tVertical deformation model of the Alpine Region\thttps://store.pangaea.de/Publications/Sanchez-etal2018/ALPS2017DEF_VT.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we have a look at the data themselves. We will use the package CSV.jl to load the comma-separated data. Let's have a look at the file ALPS2017_DEF_VT.GRD. If we open it with a text editor, we see that the data starts at line 18, and has the following format:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Column 1: Longitude [degrees]\nColumn 2: Latitude [degrees]\nColumn 3: Velocity in the height direction [m/a]\nColumn 4: Uncertainty of the height component [m/a]\n\n\n 4.00 43.00 0.000067 0.000287\n 4.30 43.00 -0.001000 0.000616\n 4.60 43.00 -0.001067 0.000544","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have 4 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ALPS2017_DEF_VT.GRD\",datarow=18,header=false,delim=' ');","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data = ParseColumns_CSV_File(data_file, 4); \njulia> lon_Vz, lat_Vz, Vz_vec = data[:,1], data[:,2], data[:,3];","category":"page"},{"location":"man/tutorial_GPS/#.-Check-and-reshape-vertical-velocity","page":"Plot GPS vectors","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's have a look at the data, by plotting it:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Plots\njulia> Plots.scatter(lon_Vz,lat_Vz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So clearly, this is a fully regular grid. We can determine the size of the grid with ","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> unique(lon_Vz)\n41-element Vector{Float64}:\n 4.0\n 4.3\n 4.6\n 4.9\n 5.2\n 5.5\n 5.8\n ⋮\n 14.5\n 14.8\n 15.1\n 15.4\n 15.7\n 16.0\njulia> unique(lat_Vz)\n31-element Vector{Float64}:\n 43.0\n 43.2\n 43.4\n 43.6\n 43.8\n 44.0\n 44.2\n ⋮\n 48.0\n 48.2\n 48.4\n 48.6\n 48.8\n 49.0","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So we have a 41 by 31 grid. GMG requires 3D matrixes for the data (as we want to plot the results in paraview in 3D). That is why we first initialize 3D matrixes for lon,lat,Vz:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon, lat, Vz = zeros(41,31,1),zeros(41,31,1),zeros(41,31,1)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And we can reshape the vectors accordingly:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> lon[:,:,1] = reshape(lon_Vz,(41,31))\njulia> lat[:,:,1] = reshape(lat_Vz,(41,31))\njulia> Vz[:,:,1] = reshape(Vz_vec,(41,31))","category":"page"},{"location":"man/tutorial_GPS/#.-Load-horizontal-velocities","page":"Plot GPS vectors","title":"3. Load horizontal velocities","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we load the horizontal velocities from the file ALPS2017_DEF_HZ.GRD","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> data_file = CSV.File(\"ALPS2017_DEF_HZ.GRD\",datarow=18,header=false,delim=' ');\njulia> data = ParseColumns_CSV_File(data_file, 6);\njulia> lon_Hz, lat_Hz, Ve_Hz, Vn_Hz = data[:,1], data[:,2], data[:,3], data[:,4];","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Let's plot the data as well:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Plots.scatter(lon_Hz,lat_Hz)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"(Image: Tutorial_GPS_2)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"So it appears that the horizontal velocities are given on the same regular grid as well, but not in the water. This thus requires a bit more work. The strategy we take is to first define 2D matrixes with horizontal velocities with the same size as Vz which are initialized with NaN (not a number), which is treated specially by Paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Ve = ones(size(Vz))*NaN;\njulia> Vn = ones(size(Vz))*NaN;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next we loop over all points in lon_Hz,lat_Hz and place them into the 2D matrixes:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> for i in eachindex(lon_Hz)\n ind = intersect(findall(x->x==lon_Hz[i], lon), findall(x->x==lat_Hz[i], lat))\n Ve[ind] .= Ve_Hz[i];\n Vn[ind] .= Vn_Hz[i];\n end","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have horizontal and vertical velocities in units of m/yr. Yet, given the small velocities in the Alps, it makes more sense to have them in units of mm/yr:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vz = Vz*1000;\njulia> Ve = Ve*1000;\njulia> Vn = Vn*1000;","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"And the magnitude is:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Vmagnitude = sqrt.(Ve.^2 + Vn.^2 + Vz.^2); ","category":"page"},{"location":"man/tutorial_GPS/#.-Interpolate-topography-on-grid","page":"Plot GPS vectors","title":"4. Interpolate topography on grid","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage we have the 3D velocity components on a grid. Yet, we don't have information yet about the elevation of the stations (as the provided data set did not give this). We could ignore that and set the elevation to zero, which would allow saving the data directly to paraview.","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Yet, a better way is to load the topographic map of the area and interpolate the elevation to the velocity grid. We are using the GMT.jl to load the topographic data:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using GMT\njulia> Elevation = gmtread(\"@earth_relief_01m.grd\", limits=[3,17,42,50]);","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Next, we use the Interpolations.jl package to interpolate the topography:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> using Interpolations\njulia> interpol = LinearInterpolation((Elevation.x[1:end-1], Elevation.y[1:end-1]), Elevation.z'); \njulia> height = interpol.(lon,lat)/1e3;","category":"page"},{"location":"man/tutorial_GPS/#.-Saving-and-plotting-in-Paraview","page":"Plot GPS vectors","title":"5. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"At this stage, we have all we need. As the velocity is a vector field, we need to save it as a data structure with 3 components. When saving to paraview, GMG internally does a vector transformation. As this transformation does not retain the east/north components of the velocity field, it is a good idea to save them as separate fields so we can color the vectors accordingly in Paraview. Also note that we do not attach units to the vector fields, but we do have them for the scalar fields:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> GPS_Sanchez_grid = GeoData(lon,lat,height,(Velocity_mm_year=(Ve,Vn,Vz),V_north=Vn*mm/yr, V_east=Ve*mm/yr, V_vertical=Vz*mm/yr, Vmagnitude = Vmagnitude*mm/yr, Topography = height*km))\nGeoData \n size : (41, 31, 1)\n lon ϵ [ 4.0 : 16.0]\n lat ϵ [ 43.0 : 49.0]\n depth ϵ [ -2.6545 km : 3.426 km]\n fields: (:Velocity_mm_year, :V_north, :V_east, :V_vertical, :Vmagnitude, :Topography)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Saving this to paraview is as always:","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"julia> Write_Paraview(GPS_Sanchez_grid, \"GPSAlps_Sanchez_2017_grid\")","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"Opening and plotting the vertical field gives: (Image: Tutorial_GPS_3)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"In order to plot the velocities as arrows, you need to select the Glyph tool (red circle). Also specify Velocity_mm_year () as both Orientation and Scale Array, and add 50 as scale factor. Once you push Apply it should look like: (Image: Tutorial_GPS_4)","category":"page"},{"location":"man/tutorial_GPS/","page":"Plot GPS vectors","title":"Plot GPS vectors","text":"The arrows can now be colored by the individual velocity components or its magnitude.","category":"page"},{"location":"man/gravity_code/#Gravity-code","page":"Gravity code","title":"Gravity code","text":"","category":"section"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"The voxGrav function allows for the voxel-based computation of Bouguer anomalies and gradients from a 3D density matrix.","category":"page"},{"location":"man/gravity_code/","page":"Gravity code","title":"Gravity code","text":"GeophysicalModelGenerator.voxGrav","category":"page"},{"location":"man/gravity_code/#GeophysicalModelGenerator.voxGrav","page":"Gravity code","title":"GeophysicalModelGenerator.voxGrav","text":"voxGrav(X::Array{Float64, 3}, Y::Array{Float64, 3}, Z::Array{Float64, 3}, RHO::Array{Float64, 3};\nrefMod=\"AVG\", lengthUnit=\"m\", rhoTol=1e-9, Topo=[], outName=\"Bouguer\", printing=true)\n\nComputes Bouguer anomalies and gradients \n\nRequired arguments: \nX,Y,Z: 3D matrices with the coordinates of the grid (X should vary in the first dimension, Y in the second, Z (vertical) in the thrid) \nRHO: 3D matrix with the densitiy at each grid point [kg/m^3] \n\nOptional arguments: \nrefMod: 1D vector with the reference density for each depth \n Alternatively, the strings \"NE\", \"SE\", \"SW\", \"NW\", \"AVG\" can be used. \n In that case, one of the corners of `RHO` is used as reference model. \n In case of \"AVG\" the reference model is the average of each depth slice. \nlengthUnit: The unit of the coordinates and topography file. Either \"m\" or \"km\" \nrhoTol: density differences smaller than rhoTol will be ignored [kg/m^3] \nTopo: 2D matrix with the topography of the surface (only relevant for the paraview output) \noutName: name of the paraview output (do not include file type) \nprinting: activate printing of additional information [true or false]\n\n\n\n\n\n","category":"function"},{"location":"man/installation/#Installation-instructions","page":"Installation","title":"Installation instructions","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"GeophysicalModelGenerator.jl is written in the julia programming language, which is an extremely powerful, modern, scientific computing language. Julia works on all major operating systems, is free, fast, and has a very active user basis (with many useful packages). In case you haven't heard about julia yet, you are not alone. Yet, perhaps a look at this or this article, which explains nicely why it has an enormous potential for computational geosciences as well.","category":"page"},{"location":"man/installation/#.-Install-julia","page":"Installation","title":"1. Install julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to use then package you obviously need to install julia. We recommend downloading and installing binaries from the julia webpage.","category":"page"},{"location":"man/installation/#.-Install-Visual-Studio-Code","page":"Installation","title":"2. Install Visual Studio Code","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The julia files itself are text files (just like matlab scripts). You may want to edit or modify them at some stage, for which you can use any text editor for that. We prefer to use the freely available Visual Studio Code as it has a build-in terminal and is the comes with the (official) julia debugger (install the Julia extension for that).","category":"page"},{"location":"man/installation/#.-Getting-started-with-julia","page":"Installation","title":"3. Getting started with julia","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You start julia on the command line with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"kausb$ julia","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will start the command-line interface of julia:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":" _\n _ _ _(_)_ | Documentation: https://docs.julialang.org\n (_) | (_) (_) |\n _ _ _| |_ __ _ | Type \"?\" for help, \"]?\" for Pkg help.\n | | | | | | |/ _` | |\n | | |_| | | | (_| | | Version 1.6.0 (2021-03-24)\n _/ |\\__'_|_|_|\\__'_| | Official https://julialang.org/ release\n|__/ |\n\njulia> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"From the julia prompt, you start the package manager by typing ]:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"(@v1.6) pkg> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"And you return to the command line with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Also useful is that julia has a build-in terminal, which you can reach by typing ; on the command line:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia>;\nshell> ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In the shell, you can use the normal commands like listing the content of a directory, or the current path:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> ls\nLICENSE Manifest.toml Project.toml README.md docs src test tutorial\nshell> pwd\n/Users/kausb/.julia/dev/GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As before, return to the main command line (called REPL) with a backspace.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want to see help information for any julia function, type ? followed by the command. An example for tan is:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"help?> tan\nsearch: tan tanh tand atan atanh atand instances transpose transcode contains UnitRange ReentrantLock StepRange StepRangeLen trailing_ones trailing_zeros\n\n tan(x)\n\n Compute tangent of x, where x is in radians.\n\n ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n\n tan(A::AbstractMatrix)\n\n Compute the matrix tangent of a square matrix A.\n\n If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the tangent. Otherwise, the tangent is determined by calling exp.\n\n Examples\n ≡≡≡≡≡≡≡≡≡≡\n\n julia> tan(fill(1.0, (2,2)))\n 2×2 Matrix{Float64}:\n -1.09252 -1.09252\n -1.09252 -1.09252","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you are in a directory that has a julia file (which have the extension *.jl), you can open that file with Visual Studio Code:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"shell> code runtests.jl","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Execute the file with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> include(\"runtests\")","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that you do not include the *.jl extension.","category":"page"},{"location":"man/installation/#.-Install-GeophysicalModelGenerator.jl","page":"Installation","title":"4. Install GeophysicalModelGenerator.jl","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"In order to install GeophysicalModelGenerator.jl, start julia and go to the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> add GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"This will automatically install various other packages it relies on (using the correct version).","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you want, you can test if it works on your machine by running the test suite in the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> test GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"Note that we run these tests automatically on Windows, Linux and Mac every time we add a new feature to GeophysicalModelGenerator (using different julia versions). This Continuous Integration (CI) ensures that new features do not break others in the package. The results can be seen here.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"The installation of GMG only needs to be done once, and will precompile the package and all other dependencies.","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you, at a later stage, want to upgrade to the latest version of GMG, you can type:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> ]\n(@v1.6) pkg> update GeophysicalModelGenerator","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"You can load GeophysicalModelGenerator, for example to create cross-sections, with:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"julia> using GeophysicalModelGenerator","category":"page"},{"location":"man/installation/#.-Other-useful-packages","page":"Installation","title":"5. Other useful packages","text":"","category":"section"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"As you will work your way through the tutorials you will see that we often use external packages, for example to load ascii data files into julia. You will find detailed instructions in the respective tutorials. ","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"If you already want to install some of those, here our favorites. Install them through the package manager:","category":"page"},{"location":"man/installation/","page":"Installation","title":"Installation","text":"CSV: Read comma-separated data files into julia. \nPlots: Create all kinds of plots in julia (quite an extensive package, but very useful to have). \nJLD2: This allows saving julia objects (such as a tomographic model) to a binary file and load it again at a later stage.\nGeodesy: Convert UTM coordinates to latitude/longitude/altitude.\nNetCDF: Read NetCDF files.\nGMT: A julia interface to the Generic Mapping Tools (GMT), which is a highly popular package to create (geophysical) maps. Note that installing GMT.jl is more complicated than installing the other packages listed above, as you first need to have a working version of GMT on your machine (it is not yet installed automatically). Installation instructions for Windows/Linux are on their webpage. On a mac, we made the best experiences by downloading the binaries from their webpage and not using a package manager to install GMT.","category":"page"},{"location":"man/visualise/#Visualisation","page":"Visualisation","title":"Visualisation","text":"","category":"section"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The standard visualisation way of GMG is to generate Paraview (VTK) files & look at them there. Yet, often we just want to have a quick look at the data without opening a new program. For that reason, we created the Visualise widget, which uses GLMakie and allows you to explore the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"It requires you to load both GLMakie and GeophysicalModelGenerator. A small example in which we load the tomography data of the alps is:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> using GeophysicalModelGenerator, GLMakie\njulia> using GMT, JLD2","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"The last line loads packages we need to read in the pre-generated JLD2 file (see the tutorials) and download topography from the region. Lets load the data, by first moving to the correct directory (will likely be different on your machine).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> ;\nshell> cd ~/Downloads/Zhao_etal_2016_data/ ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Now you can use the backspace key to return to the REPL, where we will load the data","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Data = JLD2.load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\"); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"At this stage you can look at it with","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Note that this tends to take a while, the first time you do this (faster afterwards).","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Let's add topography to the plot as well, which requires us to first load that:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Topo = ImportTopo([0,18,38,52], file=\"@earth_relief_01m.grd\");\njulia> Visualise(Data, Topography=Topo); ","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"Which will look like: (Image: Tutorial_Visualize)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"This is an example where we used GeoData to visualize results. Alternatively, we can also visualize results in km (often more useful for numerical modelling setups). For Visualize to work with this, we however need orthogonal cartesian data, which can be obtained by projecting both the data.","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> p=ProjectionPoint(Lon=10, Lat=45)\nProjectionPoint(45.0, 10.0, 578815.302916711, 4.983436768349297e6, 32, true)\njulia> Data_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,-1000:10:-1));\njulia> Topo_Cart = CartData(XYZGrid(-600:10:600,-600:10:600,0));\njulia> Topo_Cart = ProjectCartData(Topo_Cart, Topo, p)\nCartData \n size : (121, 121, 1)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -3.6270262031545473 : 3.654942280296281]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Data_Cart = ProjectCartData(Data_Cart, Data, p)\nCartData \n size : (121, 121, 100)\n x ϵ [ -600.0 : 600.0]\n y ϵ [ -600.0 : 600.0]\n z ϵ [ -1000.0 : -10.0]\n fields : (:dVp_Percentage,)\n attributes: [\"note\"]","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"And once we have done that, you can visualize the data in the same way:","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"julia> Visualise(Data_Cart, Topography=Topo_Cart)","category":"page"},{"location":"man/visualise/","page":"Visualisation","title":"Visualisation","text":"GeophysicalModelGenerator.Visualise","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#D-tomography-model-that-is-given-as-a-netCDF-file","page":"3D seismic tomography from netCDF","title":"3D tomography model that is given as a netCDF file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Goal","page":"3D seismic tomography from netCDF","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"This explains how to load a 3D seismic data set that is given in netCDF format, and plot it in paraview. The example is a shear-wave velocity model of the Alpine-Mediterranean region, described in:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"El-Sharkawy et al. (2020), The Slab Puzzle of the Alpine‐Mediterranean Region: Insights from a new, High‐Resolution, Shear‐Wave Velocity Model of the Upper Mantle, G^3 https://doi.org/10.1029/2020GC008993","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#Steps","page":"3D seismic tomography from netCDF","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Download-data","page":"3D seismic tomography from netCDF","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The data is can be downloaded from https://ds.iris.edu/files/products/emc/emc-files/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc. Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Read-data-into-Julia","page":"3D seismic tomography from netCDF","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The main data-file, El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc, is given as netCDF file. To read in data of this type, it is necessary to load an appropriate package. Here, we will use the https://github.com/JuliaGeo/NetCDF.jl package. Download and install the package with:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using Pkg\njulia> Pkg.add(\"NetCDF\")","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"First, let us have a look at the contents of this file (assuming that you are in the same directory where the file is located):","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using NetCDF\njulia> ncinfo(\"El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\")\n##### NetCDF File #####\n\n/Users/mthiel/PROJECTS/CURRENT/SPP2017/GeophysicalModelGenerator/InputData/El-Sharkawy/El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-0.0.nc\n\n##### Dimensions #####\n\nName Length \n--------------------------------------------------------------------------------------------------------------------------\ndepth 301 \nlatitude 100 \nlongitude 100 \n\n##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth \n\n##### Attributes #####\n\nVariable Name Value \n--------------------------------------------------------------------------------------------------------------------------\nglobal author_email amr.elsharkawy@ifg.uni-kiel.de \nglobal data_revision r.0.0 \nglobal author_institution Institute of Geosciences, University of Kiel, Otto-Hahn Pl..\nglobal keywords seismic tomography, shear wave, Mediterranean, phase veloc..\nglobal acknowledgment Model was provided by Dr. El-Sharkawy, Institute of Geosci..\nglobal history 2020-09-29 14:37:43 UTC Converted to netCDF by GeoCSV_2_ne..\nglobal repository_pid doi:10.17611/dp/emc.2020.meresvelsh.1 \nglobal id MeRE2020 \nglobal author_name Amr EL-Sharkawy \nglobal comment model converted to netCDF by IRIS EMC \nglobal NCO netCDF Operators version 4.7.5 (Homepage = http://nco.sf.n..\nglobal summary MeRE2020 is a high-resolution Shearâwave velocity mod..\nglobal repository_institution IRIS DMC \nglobal netCDF_file El-Sharkawy-etal-G3.2020-MeRE2020-Mediterranean-1.0.nc \nglobal author_url https://www.seismologie.ifg.uni-kiel.de \nglobal reference El-Sharkawy, et al. (2020) \nglobal repository_name EMC \nglobal Conventions CF-1.0 \nglobal Metadata_Conventions Unidata Dataset Discovery v1.0 \nglobal title The Slab Puzzle of the AlpineâMediterranean Region: I..\ndepth units km \ndepth long_name depth in km \ndepth display_name depth in km \ndepth positive down \nlatitude units degrees_north \nlatitude long_name Latitude; positive north \nlatitude standard_name latitude \nlongitude units degrees_east \nlongitude long_name Longitude; positive east \nlongitude standard_name longitude \nVs units km.s-1 \nVs long_name Shear wave velocity \nVs display_name S Velocity (km/s) ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"As you can see, there is quite some information present in this file. The most important information here are the different variables stored in this file:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"##### Variables #####\n\nName Type Dimensions \n--------------------------------------------------------------------------------------------------------------------------\ndepth FLOAT depth \nlatitude FLOAT latitude \nlongitude FLOAT longitude \nVs FLOAT longitude latitude depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Here we can see that there are four variables in this file, three of them (depth,latitude, longitude) having a single dimension and the fourth one (Vs) having dimensions of the three previous variables. The three one-dimensional vectors therefore denote a regualr grid of coordinates defining the locations where Vs is stored. To load this data, we can now simply use the commmand ncread: ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> lat = ncread(filename,\"latitude\")\njulia> lon = ncread(filename,\"longitude\")\njulia> depth = ncread(filename,\"depth\")\njulia> Vs_3D = ncread(filename,\"Vs\")\njulia> depth = -1 .* depth ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we multiplied depth with -1. This is necessary to make depth to be negative, as that is what GeophysicalModelGenerator.jl expects.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Reformat-the-coordinate-data","page":"3D seismic tomography from netCDF","title":"3. Reformat the coordinate data","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In the netCDF file, coordinates are given as 1D vectors denoting the location of nodes in a regular grid. However, GeophysicalModelGenerator.jl expects true 3D data, where each data point is assigned a latitude,longitude, depth and the respective property (here: Vs). To generate this full regular 3D grid, do the following:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Lon3D,Lat3D,Depth3D = LonLatDepthGrid(lon, lat, depth);","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Generate-Paraview-file","page":"3D seismic tomography from netCDF","title":"4. Generate Paraview file","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Once the 3D coordinate matrix has been generated, producing a Paraview file is done with the following command ","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> using GeophysicalModelGenerator\njulia> Data_set = GeoData(Lon,Lat,Depth,(Vs_km_s=Vs_3D,)) \nGeoData \n size : (100, 100, 301)\n lon ϵ [ 29.0 - 51.0]\n lat ϵ [ -11.0 - 45.9900016784668]\n depth ϵ [ -350.0 km - -50.0 km]\n fields: (:Vs_km_s,) \njulia> Write_Paraview(Data_set, \"MeRe_ElSharkawy\")\n1-element Vector{String}:\n \"MeRe_ElSharkawy.vts\"","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Plotting-data-in-Paraview","page":"3D seismic tomography from netCDF","title":"5. Plotting data in Paraview","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"In paraview you can open the file and visualize it:","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: DataPoints_Paraview)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"Note that we employ the perceptually uniform color map Barlow, which you can download here.","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"If you want to clip the data set @ 200 km depth, you need to select the Clip tool, select Sphere as a clip type, set the center to [0,0,0] and set the radius to 6171 (=radius earth - 200 km).","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"(Image: Tutorial_ElSharkawy_MeRe_DataPoints_Paraview_2)","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/#.-Julia-script","page":"3D seismic tomography from netCDF","title":"6. Julia script","text":"","category":"section"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"The full julia script that does it all is given here. You need to be in the same directory as in the data file, after which you can run it in julia with","category":"page"},{"location":"man/tutorial_loadregular3DSeismicData_netCDF/","page":"3D seismic tomography from netCDF","title":"3D seismic tomography from netCDF","text":"julia> include(\"MeRe_ElSharkawy.jl\")","category":"page"},{"location":"man/paraview_output/#Paraview-output","page":"Paraview output","title":"Paraview output","text":"","category":"section"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"We have one main routine to generate Paraview output for data that is either stored in a GeoData structure (that has lat/lon info), or ParaviewData (Cartesian). If GeoData is supplied it is internally automatically converted to the right format. Vectors, such as velocity, are also converted accordingly. You can also visualize time-dependent data.","category":"page"},{"location":"man/paraview_output/","page":"Paraview output","title":"Paraview output","text":"GeophysicalModelGenerator.Write_Paraview\nGeophysicalModelGenerator.Movie_Paraview","category":"page"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Write_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Write_Paraview","text":"pvd = Write_Paraview(DataSet::ParaviewData, filename=\"test\"; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a structure with Geodata to a paraview (or VTK) file. If you have unstructured points (e.g., earthquake data), set PointsData=true. In case you want to create a movie in Paraview, and this is a timestep of that movie you also have to pass time and pvd\n\nExample 1: Write a 3D volume\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Depthdata=Depth,LonData=Lon)) \njulia> Write_Paraview(Data_set, \"test_depth3D\")\n\nExample 2: Horizontal slice @ given depth\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 3: Case with topography\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Depth[2:4,2:4,1] .= 25km \njulia> Data_set = GeoData(Lat,Lon,Depth,(Topography=Depth,)) \njulia> Write_Paraview(Data_set, \"test2\")\n\nExample 4: Profile\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,35,(-300:25:0)km);\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth,Depth=Depth)) \njulia> Write_Paraview(Data_set, \"test\")\n\nExample 5: Velocity vectors\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:20,30:40,10km);\njulia> Ve, Vn, Vz = ones(size(Depth)), ones(size(Depth))*0.5, zeros(size(Depth));\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth, Velocity=(Ve,Vn,Vz)))\nGeoData \n size : (11, 11, 1)\n lon ϵ [ 30.0 - 40.0]\n lat ϵ [ 10.0 - 20.0]\n depth ϵ [ 10.0 km - 10.0 km]\n fields: (:DataSet, :Velocity) \njulia> Write_Paraview(Data_set, \"test_Velocity\")\n\nExample 6: Unconnected points (e.g., earthquake locations)\n\nNote that these points should be 1D vectors.\n\njulia> Lon,Lat,Depth = LonLatDepthGrid(10:5:20,35:2:40,(-300:50:0)km);\njulia> Lon=Lon[:]; Lat=Lat[:]; Depth=Depth[:];\njulia> Data_set = GeoData(Lat,Lon,Depth,(DataSet=Depth[:],Depth=Depth*10)); \njulia> Write_Paraview(Data_set, \"test_Points\", PointsData=true)\n\n\n\n\n\nWrite_Paraview(DataSet::UTMData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a UTMData structure to paraview. Note that this data is not transformed into an Earth-like framework, but remains cartesian instead. \n\n\n\n\n\nWrite_Paraview(DataSet::CartData, filename::Any; PointsData=false, pvd=nothing, time=nothing, directory=nothing, verbose=true)\n\nWrites a CartData structure to paraview. \n\n\n\n\n\n","category":"function"},{"location":"man/paraview_output/#GeophysicalModelGenerator.Movie_Paraview","page":"Paraview output","title":"GeophysicalModelGenerator.Movie_Paraview","text":"pvd = Movie_Paraview(; name=\"Movie\", pvd=pvd, Finalize::Bool=false, Initialize::Bool=true)\n\nIf you want to make a movie of your data set, you can use this routine to initialize and to finalize the movie-file. It will create a *.pvd file, which you can open in Paraview \n\nIndividual timesteps are added to the movie by passing pvd and the time of the timestep to the Write_Paraview routine.\n\nExample\n\nUsually this is used inside a *.jl script, as in this pseudo-example:\n\nmovie = Movie_Paraview(name=\"Movie\", Initialize=true)\nfor itime=1:10\n name = \"test\"*string(itime)\n movie = Write_Paraview(Data, name, pvd=movie, time=itime)\nend\nMovie_Paraview(pvd=movie, Finalize=true)\n\n\n\n\n\n","category":"function"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"EditURL = \"/Tutorial_Votemaps.jl\"","category":"page"},{"location":"man/Tutorial_Votemaps/#Votemaps","page":"VoteMaps","title":"Votemaps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#Aim","page":"VoteMaps","title":"Aim","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In this tutorial, your will learn how to create Votemaps that compare different tomographic models and look for similarities between different models.","category":"page"},{"location":"man/Tutorial_Votemaps/#Steps","page":"VoteMaps","title":"Steps","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/#.-Load-data","page":"VoteMaps","title":"1. Load data","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"We assume that you have all tomographic models already available as *.JLD2 files. In our example we use the data uploaded to https://seafile.rlp.net/d/22b0fb85550240758552/","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Specifically, we will use the tomographic models of Paffrath, Zhao and Koulakov, as we have them all available in processed form Download the corresponding *.jld2 files to the same directory","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"using JLD2, GeophysicalModelGenerator\n\nPwave_Zhao = load(\"Zhao_Pwave.jld2\",\"Data_set_Zhao2016_Vp\")\nPSwave_Koulakov = load(\"Koulakov_Europe.jld2\",\"DataKoulakov_Alps\")\nPwave_Paffrath = load(\"Paffrath_Pwave.jld2\",\"Data_set_Paffrath2021_Vp\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The 3 data sets all contain tomographic models for roughly the alpine area, but as you can see, they all have a different resolution and the fields are sometimes called different as well:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Pwave_Paffrath\nGeoData\n size : (162, 130, 42)\n lon ϵ [ -13.3019 : 35.3019]\n lat ϵ [ 30.7638 : 61.2362]\n depth ϵ [ -606.0385 km : 31.0385 km]\n fields: (:dVp_Percentage, :Vp, :Resolution)\n\nPSwave_Koulakov\n GeoData\n size : (108, 81, 35)\n lon ϵ [ 4.0 : 20.049999999999997]\n lat ϵ [ 37.035928143712574 : 49.01197604790419]\n depth ϵ [ -700.0 km : -10.0 km]\n fields: (:dVp_percentage, :dVs_percentage)","category":"page"},{"location":"man/Tutorial_Votemaps/#.-Creating-a-Votemap","page":"VoteMaps","title":"2. Creating a Votemap","text":"","category":"section"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The idea of Votemaps is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"assume that a certain perturbation describes a feature (say, P wave anomalies >3% are interpreted to be slabs in the model of Paffrath)\nEverything that fulfills this criteria gets the number 1, everything else 0.\nDo the same with other tomographic models (using the same criteria or a different one).\nMake sure that all tomographic models are interpolated to the same grid.\nSum up the 3 models.\nThe resulting 3D map will have the number 3 at locations where all 3 models see a high-velocity anomaly (say a slab), implying that this feature is consistent between all models. Features that have a number 1 or 2 are only seen in a single or in 2/3 models.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"The result of this gives a feeling which features are consistent between the 3 models. It is ofcourse still subjective, as you still have to choose a criteria and as we are assuming in this that the 3 tomographic models are comparable (which they are not as they are produced using different amounts of datam, etc. etc.)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"So how do we create Votemaps? Doing this is rather simple:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"], dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This will look at the common lon,lat,depth ranges between all 3 models, interpret each of the models to a common grid of size (100,100,100) and apply each of the criteria specified The resulting GeoData struct looks like:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"GeoData\n size : (100, 100, 100)\n lon ϵ [ 4.0 : 18.0]\n lat ϵ [ 38.0 : 49.01197604790419]\n depth ϵ [ -606.0385 km : -10.0 km]\n fields: (:VoteMap,)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"And from this, we can generate profiles, visualize 3D features in Paraview etc. etc.","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Write_Paraview(Data_VoteMap, \"VoteMap_Alps\")","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"In paraview, this gives (Image: Tutorial_VoteMap)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"You can ofcourse argue that newer tomographic models include more data & should therefore count more A simple way to take that into account is to list the model twice:","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Data_VoteMap = VoteMap( [Pwave_Paffrath, Pwave_Paffrath, PSwave_Koulakov, Pwave_Zhao],\n [\"dVp_Percentage>3.0\",\"dVp_Percentage>3.0\", \"dVp_percentage>2.0\",\"dVp_Percentage>2.0\"],\n dims=(100,100,100))","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"Similarly, you could only look at a single model (even when that is perhaps easier done directly in paraview, where you can simply select a different isocontour value)","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"","category":"page"},{"location":"man/Tutorial_Votemaps/","page":"VoteMaps","title":"VoteMaps","text":"This page was generated using Literate.jl.","category":"page"},{"location":"man/projection/#Projecting-and-converting-data","page":"Projection","title":"Projecting & converting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Typically, you load a dataset by reading it into julia and either generating a GeoData structure (in case you have longitude/latitude/depth info), or as UTMData (in case the data is in UTM coordinates, which requires you to specify the zone & hemisphere).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"If you write the data to Paraview, it is internally converted to a Paraview structure (which involves x,y,z Cartesian Earth-Centered-Earth-Fixed (ECEF) coordinates using the wgs84 ellipsoid). ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, if you do geodynamic calculations the chances are that the geodynamic code does not operate in spherical coordinates, but rather use cartesian ones. In that case you should transfer your data to the CartData structure, which requires you to specify a ProjectionPoint that is a point on the map that will later have the coordinates (0,0) in the CartData structure.","category":"page"},{"location":"man/projection/#.-Converting","page":"Projection","title":"1. Converting","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Converting from one coordinate system to the other is straightforward. Let's use Europe as an example:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo(lon = [-10, 45], lat=[25, 50], file=\"@earth_relief_20m\")\nGeoData \n size : (165, 75, 1)\n lon ϵ [ -10.0 : 44.666666666666664]\n lat ϵ [ 25.0 : 49.666666666666664]\n depth ϵ [ -4.9855 km : 3.123 km]\n fields: (:Topography,)\njulia> Write_Paraview(Topo,\"Topo\")\nSaved file: Topo.vts","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"The result is shown on the globe as: (Image: Topo_Europe_GeoData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can convert this to UTM zone as:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> convert(UTMData, Topo)\nUTMData \n UTM zone : 29-38 North\n size : (165, 75, 1)\n EW ϵ [ 197181.31221507967 : 769155.4572884373]\n NS ϵ [ 2.7649477474783654e6 : 5.505892073781423e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"As the area is large, it covers a range of UTM zones (and every point has a UTM zone attached). Within each zone, the coordinates are approximately orthogonal. Plotting this to Paraview does not result in a sensible dataset.","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Yet, what we could do instead is show all data with respect to a single UTM zone. For this, we have to select a point around which we project (in this case more or less in the center):","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> p=ProjectionPoint(Lon=17.3, Lat=37.5)\nProjectionPoint(37.5, 17.3, 703311.4380385976, 4.152826288024972e6, 33, true)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Projecting the GeoData set using this projection point is done with:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Convert2UTMzone(Topo,p)\nUTMData \n UTM zone : 33-33 North\n size : (165, 75, 1)\n EW ϵ [ -2.0750691599137965e6 : 3.581351293385453e6]\n NS ϵ [ 2.7649477474783654e6 : 5.938114212160672e6]\n depth ϵ [ -4985.5 m : 3123.0 m]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is now in UTM Data (in meters), it is distorted. (Image: Topo_Europe_UTMData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Often it is more convenient to have this in CartData, which is done in a similar manner:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart = Convert2CartData(Topo,p)\nCartData \n size : (165, 75, 1)\n x ϵ [ -2778.3805979523936 km : 2878.039855346856 km]\n y ϵ [ -1387.8785405466067 km : 1785.2879241356998 km]\n z ϵ [ -4.9855 km : 3.123 km]\n fields : (:Topography,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"This shows that the model is ~5600 by 3000 km. (Image: Topo_Europe_CartData)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Whereas this is ok to look at and compare with a LaMEM model setup, we cannot use it to perform internal calculations (or to generate a LaMEM model setup), because the x and y coordinates are distorted and not orthogonal. ","category":"page"},{"location":"man/projection/#.-Projecting-data","page":"Projection","title":"2. Projecting data","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"For use with LaMEM, you would need an orthogonal cartesian grid. From the last command above we get some idea on the area, so we can create this:","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = CartData(XYZGrid(-2000:20:2000,-1000:20:1000,0))\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ 0.0 km : 0.0 km]\n fields : (:Z,)","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"Next, we can project the topographic data (in GeoData format) on this orthogonal grid","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"julia> Topo_Cart_orth = ProjectCartData(Topo_Cart_orth, Topo, p)\nCartData \n size : (201, 101, 1)\n x ϵ [ -2000.0 km : 2000.0 km]\n y ϵ [ -1000.0 km : 1000.0 km]\n z ϵ [ -4.485650671162607 km : 2.5909655318121865 km]\n fields : (:Topography,)\njulia> Write_Paraview(Topo_Cart_orth,\"Topo_Cart_orth\"); ","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"(Image: Topo_Europe_CartData_Proj) So this interpolates the topographic data from the GeoData to the orthogonal cartesian grid (which can be used with LaMEM, for example).","category":"page"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"You can do similar projections with full 3D data sets or pointwise data. ","category":"page"},{"location":"man/projection/#.-List-of-functions","page":"Projection","title":"3. List of functions","text":"","category":"section"},{"location":"man/projection/","page":"Projection","title":"Projection","text":"GeophysicalModelGenerator.Convert2CartData\nGeophysicalModelGenerator.ProjectCartData\nGeophysicalModelGenerator.Convert2UTMzone","category":"page"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2CartData","page":"Projection","title":"GeophysicalModelGenerator.Convert2CartData","text":"Convert2CartData(d::UTMData, proj::ProjectionPoint)\n\nConverts a UTMData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\nConvert2CartData(d::GeoData, proj::ProjectionPoint)\n\nConverts a GeoData structure to a CartData structure, which essentially transfers the dimensions to km\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.ProjectCartData","page":"Projection","title":"GeophysicalModelGenerator.ProjectCartData","text":"d_cart = ProjectCartData(d_cart::CartData, d::GeoData, p::ProjectionPoint)\n\nProjects all datafields from the GeoData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\nNote:\n\nIf d_cart and d are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate. \n\n\n\n\n\nd_cart = ProjectCartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)\n\nProjects all datafields from the UTMData struct d to the CartData struct d_cart, around the projection point p. d_cart must be an orthogonal cartesian grid (deformed doesn't work; use Convert2CartData(d, proj), where proj is a projection point in that case).\n\n# Note: \n- If `d_cart` and `d` are horizontal surfaces (3rd dimension has size==1), it also interpolates the depth coordinate.\n\n\n\n\n\n","category":"function"},{"location":"man/projection/#GeophysicalModelGenerator.Convert2UTMzone","page":"Projection","title":"GeophysicalModelGenerator.Convert2UTMzone","text":"Convert2UTMzone(d::GeoData, p::ProjectionPoint)\n\nConverts a GeoData structure to fixed UTM zone, around a given ProjectionPoint This useful to use real data as input for a cartesian geodynamic model setup (such as in LaMEM). In that case, we need to project map coordinates to cartesian coordinates. One way to do this is by using UTM coordinates. Close to the ProjectionPoint the resulting coordinates will be rectilinear and distance in meters. The map distortion becomes larger the further you are away from the center.\n\n\n\n\n\nConvert2UTMzone(d::CartData, proj::ProjectionPoint)\n\nThis transfers a CartData dataset to a UTMData dataset, that has a single UTM zone. The point around which we project is ProjectionPoint\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_UTM/#Read-in-UTM-data","page":"Read UTM data","title":"Read in UTM data","text":"","category":"section"},{"location":"man/tutorial_UTM/#Goal","page":"Read UTM data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The aim of this tutorial is to show you how you can read in data that is given in UTM coordinates. The example we use is the 3D density model of the Alps derived by Spooner et al. (2010), which you can download following the link from","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D ALPS: 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. V. 2.0. GFZ Data Services. https://doi.org/10.5880/GFZ.4.5.2019.004","category":"page"},{"location":"man/tutorial_UTM/#Steps","page":"Read UTM data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_UTM/#.-Download-and-import-UTM-data:","page":"Read UTM data","title":"1. Download and import UTM data:","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Download the data file 2019-004_Spooner_Lithospheric Mantle.txt from http://doi.org/10.5880/GFZ.4.5.2019.004 and make sure that you change to the directory using julia. If you open the data with a text editor, you'll see that it looks like:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"# These data are freely available under the Creative Commons Attribution 4.0 International Licence (CC BY 4.0)\t\t\t\t\t\n# when using the data please cite as: \t\t\t\t\t\n# Spooner, Cameron; Scheck-Wenderoth, Magdalena; Götze, Hans-Jürgen; Ebbing, Jörg; Hetényi, György (2019): 3D Gravity Constrained Model of Density Distribution Across the Alpine Lithosphere. GFZ Data Services. http://doi.org/10.5880/GFZ.4.5.2019.004\nX COORD (UTM Zone 32N)\tY COORD (UTM Zone 32N)\tTOP (m.a.s.l)\tTHICKNESS (m)\tDENSITY (Kg/m3)\n286635\t4898615\t-24823.2533\t70418.125\t3305\n286635\t4918615\t-25443.48901\t69410.01563\t3305\n286635\t4938615\t-28025.24511\t66402.49219\t3305\n286635\t4958615\t-32278.13135\t61663.48438\t3305\n286635\t4978615\t-35885.5625\t57459.14063\t3305\n286635\t4998615\t-37270.9812\t55318.71094\t3305\n286635\t5018615\t-36134.30481\t55497.16406\t3305\n286635\t5038615\t-34866.0697\t55555.41406\t3305","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So we have 5 columns with data values, and the data is separated by spaces. We can load that in julia as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> using DelimitedFiles, GeophysicalModelGenerator\njulia> data=readdlm(\"2019-004_Spooner_Lithospheric Mantle.txt\",skipstart=4)\n1023×5 Matrix{Float64}:\n 286635.0 4.89862e6 -24823.3 70418.1 3305.0\n 286635.0 4.91862e6 -25443.5 69410.0 3305.0\n 286635.0 4.93862e6 -28025.2 66402.5 3305.0\n 286635.0 4.95862e6 -32278.1 61663.5 3305.0\n ⋮ \n 926635.0 5.45862e6 -35302.7 83215.6 3335.0\n 926635.0 5.47862e6 -34908.6 84203.0 3335.0\n 926635.0 5.49862e6 -34652.4 85398.3 3335.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can read the numerical data from the file with:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> ew, ns, depth, thick, rho = data[:,1], data[:,2], data[:,3], data[:,4], data[:,5];","category":"page"},{"location":"man/tutorial_UTM/#.-Check-and-reshape-vertical-velocity","page":"Read UTM data","title":"2. Check & reshape vertical velocity","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"The data is initially available as 1D columns, which needs to be reshaped into 2D arrays. We first reshape it into 2D arrays (using reshape). Yet, if we later want to visualize a perturbed surface in paraview, we need to save this as a 3D array (with 1 as 3rd dimension).","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> res = ( length(unique(ns)), length(unique(ew)), 1)\njulia> EW = reshape(ew,res) \njulia> NS = reshape(ns,res)\njulia> Depth = reshape(depth,res)\njulia> T = reshape(thick,res)\njulia> Rho = reshape(rho,res)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can examine EW: ","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW\n31×33×1 Array{Float64, 3}:\n[:, :, 1] =\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n ⋮ ⋮ ⋱ ⋮ \n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0\n 286635.0 306635.0 326635.0 346635.0 366635.0 386635.0 406635.0 … 826635.0 846635.0 866635.0 886635.0 906635.0 926635.0","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"So, on fact, the EW array varies in the 2nd dimension. It should, however, vary in the first dimension which is why we need to apply a permutation & switch the first and second dimensions:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> EW = permutedims(EW,[2 1 3]) \njulia> NS = permutedims(NS,[2 1 3]) \njulia> Depth = permutedims(Depth,[2 1 3]) \njulia> T = permutedims(T,[2 1 3]) \njulia> Rho = permutedims(Rho,[2 1 3]) ","category":"page"},{"location":"man/tutorial_UTM/#.-Create-UTMData-structure","page":"Read UTM data","title":"3. Create UTMData structure","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Next we can add the data to the UTMData structure. In this, we use the information that the UTM zone was 32 North.","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM = UTMData(EW,NS,Depth,32, true, (Thickness=T/1e3*km, Density=Rho*kg/m^3 ))\nUTMData \n UTM zone : 32-32 North\n size : (33, 31, 1)\n EW ϵ [ 286635.0 : 926635.0]\n NS ϵ [ 4.898615e6 : 5.498615e6]\n depth ϵ [ -52579.56788 m : -20873.400850000003 m]\n fields : (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/#.-Saving-and-plotting-in-Paraview","page":"Read UTM data","title":"4. Saving and plotting in Paraview","text":"","category":"section"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"We can transfer this into a GeoData structure as:","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Data_LM_lonlat = convert(GeoData,Data_LM)\nGeoData \n size : (33, 31, 1)\n lon ϵ [ 6.046903388679526 : 14.892535147436673]\n lat ϵ [ 44.11618022783332 : 49.64004892531006]\n depth ϵ [ -52.57956788 km : -20.873400850000003 km]\n fields: (:Thickness, :Density)","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"and save it to Paraview in the usual way","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"julia> Write_Paraview(Data_LM_lonlat, \"Data_LM_lonlat\")","category":"page"},{"location":"man/tutorial_UTM/","page":"Read UTM data","title":"Read UTM data","text":"Opening and plotting the vertical field gives: (Image: Tutorial_UTM)","category":"page"},{"location":"man/lamem/#LaMEM","page":"LaMEM","title":"LaMEM","text":"","category":"section"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"In order to generate geodynamic simulations from setups created with GeophysicalModelGenerator.jl, we provide a few routines that directly create marker input files for the 3D geodynamic modelling software LaMEM, which is an open-source cartesian code that is well-suited to perform crustal and lithospheric-scale simulations. If you want to learn how to run LaMEM simulations, please have a look at the wiki page. ","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"The routines provided here have the following functionality:","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"Read LaMEM *.dat files (to get the size of the domain)\nRead LaMEM processor partitioning file\nAdd lithospheric boxes to a setup, that may have a layered structure and various thermal structures\nSave LaMEM marker files in serial or in parallel\nRead a LaMEM timestep","category":"page"},{"location":"man/lamem/","page":"LaMEM","title":"LaMEM","text":"GeophysicalModelGenerator.ReadLaMEM_InputFile\nGeophysicalModelGenerator.GetProcessorPartitioning\nGeophysicalModelGenerator.Save_LaMEMTopography\nGeophysicalModelGenerator.Save_LaMEMMarkersParallel\nGeophysicalModelGenerator.ReadData_PVTR\nGeophysicalModelGenerator.AddBox!\nGeophysicalModelGenerator.AddSphere!\nGeophysicalModelGenerator.AddEllipsoid!\nGeophysicalModelGenerator.AddCylinder!\nGeophysicalModelGenerator.makeVolcTopo\nGeophysicalModelGenerator.ConstantTemp\nGeophysicalModelGenerator.LinearTemp\nGeophysicalModelGenerator.HalfspaceCoolingTemp\nGeophysicalModelGenerator.SpreadingRateTemp\nGeophysicalModelGenerator.ConstantPhase\nGeophysicalModelGenerator.Compute_Phase\nGeophysicalModelGenerator.LithosphericPhases\nGeophysicalModelGenerator.LaMEM_grid\nGeophysicalModelGenerator.CreatePartitioningFile","category":"page"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadLaMEM_InputFile","page":"LaMEM","title":"GeophysicalModelGenerator.ReadLaMEM_InputFile","text":"Grid::LaMEM_grid = ReadLaMEM_InputFile(file)\n\nParses a LaMEM input file and stores grid information in the Grid structure.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"SaltModels.dat\") \nLaMEM Grid: \nnel : (32, 32, 32)\nmarker/cell : (3, 3, 3)\nmarkers : (96, 96, 96)\nx ϵ [-3.0 : 3.0]\ny ϵ [-2.0 : 2.0]\nz ϵ [-2.0 : 0.0]\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.GetProcessorPartitioning","page":"LaMEM","title":"GeophysicalModelGenerator.GetProcessorPartitioning","text":"nProcX,nProcY,nProcZ, xc,yc,zc, nNodeX,nNodeY,nNodeZ = GetProcessorPartitioning(filename)\n\nReads a LaMEM processor partitioning file, used to create marker files, and returns the parallel layout \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMTopography","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMTopography","text":"Save_LaMEMTopography(Topo::CartData, filename::String)\n\nThis writes a topography file Topo for use in LaMEM, which should have size (nx,ny,1) and contain the field :Topography \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.Save_LaMEMMarkersParallel","page":"LaMEM","title":"GeophysicalModelGenerator.Save_LaMEMMarkersParallel","text":"Save_LaMEMMarkersParallel(Grid::CartData; PartitioningFile=empty, directory=\"./markers\", verbose=true)\n\nSaves a LaMEM marker file from the CartData structure Grid. It must have a field called Phases, holding phase information (as integers) and optionally a field Temp with temperature info. It is possible to provide a LaMEM partitioning file PartitioningFile. If not, output is assumed to be for one processor.\n\nThe size of Grid should be consistent with what is provided in the LaMEM input file. In practice, the size of the mesh can be retrieved from a LaMEM input file using ReadLaMEM_InputFile.\n\nExample\n\njulia> Grid = ReadLaMEM_InputFile(\"LaMEM_input_file.dat\")\njulia> Phases = zeros(Int32,size(Grid.X));\njulia> Temp = ones(Float64,size(Grid.X));\njulia> Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\njulia> Save_LaMEMMarkersParallel(Model3D)\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n\nIf you want to create a LaMEM input file for multiple processors:\n\njulia> Save_LaMEMMarkersParallel(Model3D, PartitioningFile=\"ProcessorPartitioning_4cpu_1.2.2.bin\")\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\nWriting LaMEM marker file -> ./markers/mdb.00000001.dat\nWriting LaMEM marker file -> ./markers/mdb.00000002.dat\nWriting LaMEM marker file -> ./markers/mdb.00000003.dat\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ReadData_PVTR","page":"LaMEM","title":"GeophysicalModelGenerator.ReadData_PVTR","text":"Data::ParaviewData = ReadData_PVTR(fname, dir)\n\nReads a parallel, rectilinear, *.vts file with the name fname and located in dir and create a 3D Data struct from it.\n\nExample\n\njulia> Data = ReadData_PVTR(\"Haaksbergen.pvtr\", \"./Timestep_00000005_3.35780500e-01/\")\nParaviewData \n size : (33, 33, 33)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ -2.0 : 0.0]\n fields: (:phase, :density, :visc_total, :visc_creep, :velocity, :pressure, :temperature, :dev_stress, :strain_rate, :j2_dev_stress, :j2_strain_rate, :plast_strain, :plast_dissip, :tot_displ, :yield, :moment_res, :cont_res)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddBox!","page":"LaMEM","title":"GeophysicalModelGenerator.AddBox!","text":"AddBox!(Phase, Temp, Grid::AbstractGeneralGrid; xlim=Tuple{2}, [ylim=Tuple{2}], zlim=Tuple{2},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1),\n T=nothing )\n\nAdds a box with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - grid structure (usually obtained with ReadLaMEM_InputFile, but can also be other grid types)\nxlim - left/right coordinates of box\nylim - front/back coordinates of box [optional; if not specified we use the whole box]\nzlim - bottom/top coordinates of box\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExamples\n\nExample 1) Box with constant phase and temperature & a dip angle of 10 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\nExample 2) Box with halfspace cooling profile\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddBox!(Phases,Temp,Grid, xlim=(0,500), zlim=(-50,0), phase=ConstantPhase(3), DipAngle=10, T=ConstantTemp(1000))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddSphere!","page":"LaMEM","title":"GeophysicalModelGenerator.AddSphere!","text":"AddSphere!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a sphere with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\nradius - radius of sphere\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nSphere with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddSphere!(Phases,Temp,Grid, cen=(0,0,-1), radius=0.5, phase=ConstantPhase(2), T=ConstantTemp(800))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddEllipsoid!","page":"LaMEM","title":"GeophysicalModelGenerator.AddEllipsoid!","text":"AddEllipsoid!(Phase, Temp, Grid::AbstractGeneralGrid; cen=Tuple{3}, axes=Tuple{3},\n Origin=nothing, StrikeAngle=0, DipAngle=0,\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds an Ellipsoid with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - LaMEM grid structure (usually obtained with ReadLaMEM_InputFile)\ncen - center coordinates of sphere\naxes - semi-axes of ellipsoid in X,Y,Z\nOrigin - the origin, used to rotate the box around. Default is the left-front-top corner\nStrikeAngle - strike angle of slab\nDipAngle - dip angle of slab\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nEllipsoid with constant phase and temperature, rotated 90 degrees and tilted by 45 degrees:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddEllipsoid!(Phases,Temp,Grid, cen=(-1,-1,-1), axes=(0.2,0.1,0.5), StrikeAngle=90, DipAngle=45, phase=ConstantPhase(3), T=ConstantTemp(600))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.AddCylinder!","page":"LaMEM","title":"GeophysicalModelGenerator.AddCylinder!","text":"AddCylinder!(Phase, Temp, Grid::AbstractGeneralGrid; base=Tuple{3}, cap=Tuple{3}, radius=Tuple{1},\n phase = ConstantPhase(1).\n T=nothing )\n\nAdds a cylinder with phase & temperature structure to a 3D model setup. This simplifies creating model geometries in geodynamic models\n\nParameters\n\nPhase - Phase array (consistent with Grid)\nTemp - Temperature array (consistent with Grid)\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\nbase - center coordinate of bottom of cylinder\ncap - center coordinate of top of cylinder\nradius - radius of the cylinder\nphase - specifies the phase of the box. See ConstantPhase(),LithosphericPhases() \nT - specifies the temperature of the box. See ConstantTemp(),LinearTemp(),HalfspaceCoolingTemp(),SpreadingRateTemp() \n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Phases = zeros(Int32, size(Grid.X));\njulia> Temp = zeros(Float64, size(Grid.X));\njulia> AddCylinder!(Phases,Temp,Grid, base=(-1,-1,-1.5), cap=(1,1,-0.5), radius=0.25, phase=ConstantPhase(4), T=ConstantTemp(400))\njulia> Model3D = ParaviewData(Grid, (Phases=Phases,Temp=Temp)); # Create Cartesian model\njulia> Write_Paraview(Model3D,\"LaMEM_ModelSetup\") # Save model to paraview \n1-element Vector{String}:\n \"LaMEM_ModelSetup.vts\" \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.makeVolcTopo","page":"LaMEM","title":"GeophysicalModelGenerator.makeVolcTopo","text":"makeVolcTopo(Grid::LaMEM_grid; center::Array{Float64, 1}, height::Float64, radius::Float64, crater::Float64, base=0.0m, background=nothing)\n\nCreates a generic volcano topography (cones and truncated cones)\n\nParameters\n\nGrid - LaMEM grid (created by ReadLaMEM_InputFile)\ncenter - x- and -coordinates of center of volcano\nheight - height of volcano\nradius - radius of volcano\n\nOptional Parameters\n\ncrater - this will create a truncated cone and the option defines the radius of the flat top\nbase - this sets the flat topography around the volcano\nbackground - this allows loading in a topography and only adding the volcano on top (also allows stacking of several cones to get a volcano with different slopes)\n\nExample\n\nCylinder with constant phase and temperature:\n\njulia> Grid = ReadLaMEM_InputFile(\"test_files/SaltModels.dat\")\nLaMEM Grid: \n nel : (32, 32, 32)\n marker/cell : (3, 3, 3)\n markers : (96, 96, 96)\n x ϵ [-3.0 : 3.0]\n y ϵ [-2.0 : 2.0]\n z ϵ [-2.0 : 0.0]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.4, radius=1.5, crater=0.5, base=0.1)\nCartData \n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.4]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Topo = makeVolcTopo(Grid, center=[0.0,0.0], height=0.8, radius=0.5, crater=0.0, base=0.4, background=Topo.fields.Topography)\nCartData \n size : (33, 33, 1)\n x ϵ [ -3.0 : 3.0]\n y ϵ [ -2.0 : 2.0]\n z ϵ [ 0.1 : 0.8]\n fields : (:Topography,)\n attributes: [\"note\"]\njulia> Write_Paraview(Topo,\"VolcanoTopo\") # Save topography to paraview \nSaved file: VolcanoTopo.vts \n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantTemp","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantTemp","text":"ConstantTemp(T=1000)\n\nSets a constant temperature inside the box\n\nParameters\n\nT : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LinearTemp","page":"LaMEM","title":"GeophysicalModelGenerator.LinearTemp","text":"LinearTemp(Ttop=0, Tbot=1000)\n\nSet a linear temperature structure from top to bottom\n\nParameters\n\nTtop : the value @ the top\nTbot : the value @ the bottom\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.HalfspaceCoolingTemp","page":"LaMEM","title":"GeophysicalModelGenerator.HalfspaceCoolingTemp","text":"HalfspaceCoolingTemp(Tsurface=0, Tmantle=1350, Age=60, Adiabat=0)\n\nSets a halfspace temperature structure in plate\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAge : Thermal Age of plate [Myrs]\nAdiabat : Mantle Adiabat [K/km]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.SpreadingRateTemp","page":"LaMEM","title":"GeophysicalModelGenerator.SpreadingRateTemp","text":"SpreadingRateTemp(Tsurface=0, Tmantle=1350, Adiabat=0, MORside=\"left\",SpreadingVel=3, AgeRidge=0, maxAge=80)\n\nSets a halfspace temperature structure within the box, combined with a spreading rate (which implies that the plate age varies)\n\nParameters\n\nTsurface : surface temperature [C]\nTmantle : mantle temperature [C]\nAdiabat : Mantle Adiabat [K/km]\nMORside : side of the box where the MOR is located [\"left\",\"right\",\"front\",\"back\"]\nSpreadingVel : spreading velocity [cm/yr]\nAgeRidge : thermal age of the ridge [Myrs]\nmaxAge : maximum thermal Age of plate [Myrs]\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.ConstantPhase","page":"LaMEM","title":"GeophysicalModelGenerator.ConstantPhase","text":"ConstantPhase(phase=1)\n\nSets a constant phase inside the box\n\nParameters\n\nphase : the value\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.Compute_Phase","page":"LaMEM","title":"GeophysicalModelGenerator.Compute_Phase","text":"Phase = Compute_Phase(Phase, Temp, X, Y, Z, s::LithosphericPhases, Ztop)\n\nor\n\nPhase = Compute_Phase(Phase, Temp, Grid::AbstractGeneralGrid, s::LithosphericPhases)\n\nThis copies the layered lithosphere onto the Phase matrix.\n\nParameters\n\nPhase - Phase array\nTemp - Temperature array\nX - x-coordinate array (consistent with Phase and Temp)\nY - y-coordinate array (consistent with Phase and Temp)\nZ - Vertical coordinate array (consistent with Phase and Temp)\ns - LithosphericPhases\nZtop - Vertical coordinate of top of model box\nGrid - Grid structure (usually obtained with ReadLaMEM_InputFile)\n\n\n\n\n\n","category":"function"},{"location":"man/lamem/#GeophysicalModelGenerator.LithosphericPhases","page":"LaMEM","title":"GeophysicalModelGenerator.LithosphericPhases","text":"LithosphericPhases(Layers=[10 20 15], Phases=[1 2 3 4], Tlab=nothing )\n\nThis allows defining a layered lithosphere. Layering is defined from the top downwards.\n\nParameters\n\nLayers : The thickness of each layer, ordered from top to bottom. The thickness of the last layer does not have to be specified.\nPhases : The phases of the layers, ordered from top to bottom.\nTlab : Temperature of the lithosphere asthenosphere boundary. If specified, the phases at locations with T>Tlab are set to Phases[end].\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.LaMEM_grid","page":"LaMEM","title":"GeophysicalModelGenerator.LaMEM_grid","text":"Structure that holds information about the LaMEM grid (usually read from an input file).\n\n\n\n\n\n","category":"type"},{"location":"man/lamem/#GeophysicalModelGenerator.CreatePartitioningFile","page":"LaMEM","title":"GeophysicalModelGenerator.CreatePartitioningFile","text":"CreatePartitioningFile(LaMEM_input::String, NumProc::Int64; LaMEM_dir::String=pwd(), LaMEM_options::String=\"\", MPI_dir=\"\", verbose=true)\n\nThis executes LaMEM for the input file LaMEM_input & creates a parallel partitioning file for NumProc processors. The directory where the LaMEM binary is can be specified; if not it is assumed to be in the current directory. Likewise for the mpiexec directory (if not specified it is assumed to be available on the command line).\n\n\n\n\n\n","category":"function"},{"location":"man/tutorial_GMT_Topography/#Extract-topographic-data-from-GMT.jl","page":"Create GMT-based topography","title":"Extract topographic data from GMT.jl","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#Goal","page":"Create GMT-based topography","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In many cases, we want to add topographic data as well to our visualization. This tutorial shows how to use GMT.jl to download data from a certain region, and transfer that.","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"note: Note\nIt may be tricky to get GMT.jl installed and working correctly on your system (at least until someone prevides a BinaryBuilder package for julia, that is). You first need to have a working version of GMT on your system and only after that, you can install GMT.jl. See the installation instructions on their webpage for details. On a MacBook Pro, a tested procedure to install GMT and to make it work with julia is to directly install the binaries for Julia, GMT (and possibly Ghostscript) and not use any package manager (such as spack or homebrew). ","category":"page"},{"location":"man/tutorial_GMT_Topography/#Steps","page":"Create GMT-based topography","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/#.-Download-topographic-data-of-the-Alpine-region","page":"Create GMT-based topography","title":"1. Download topographic data of the Alpine region","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The nice thing about GMT is that it automatically downloads data for you for a certain region and with a certain resolution. As this is a routine that you may use often in your daily workflow, we added the function ImportTopo that simplifies this. Note that this function only is available once GMT is loaded. ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> using GeophysicalModelGenerator, GMT\njulia> Topo = ImportTopo([4,20,37,49], file=\"@earth_relief_01m.grd\")\nGeoData \n size : (960, 720, 1)\n lon ϵ [ 4.0 : 19.983333333333334]\n lat ϵ [ 37.0 : 48.983333333333334]\n depth ϵ [ -3.8725 km : 4.2495 km]\n fields: (:Topography,)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The data is available in different resolutions; see here for an overview. Generally, it is advisable to not use the largest resolution if you have a large area. ","category":"page"},{"location":"man/tutorial_GMT_Topography/#.-Save","page":"Create GMT-based topography","title":"2. Save","text":"","category":"section"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"Transforming this to Paraview is a piece of cake:","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"julia> Write_Paraview(Topo, \"Topography_Alps\") ","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"(Image: Tutorial_GMT_topography)","category":"page"},{"location":"man/tutorial_GMT_Topography/","page":"Create GMT-based topography","title":"Create GMT-based topography","text":"In case you are interested: we are employing the oleron scientific colormap here.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EditURL = \"/LaPalma_example.jl\"","category":"page"},{"location":"man/LaPalma_example/#Create-a-3D-LaMEM-setup-for-La-Palma","page":"Generating LaMEM model","title":"Create a 3D LaMEM setup for La Palma","text":"","category":"section"},{"location":"man/LaPalma_example/#Aim","page":"Generating LaMEM model","title":"Aim","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this tutorial, your will learn how to use real data to create a geodynamic model setup with LaMEM. We will use the data of La Palma, which is a volcanic island that started erupting in mid september 2021. LaMEM is a cartesian geodynamic model, which implies that you will have to transfer the data from GeoData to CartData.","category":"page"},{"location":"man/LaPalma_example/#.-Load-data","page":"Generating LaMEM model","title":"1. Load data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We will use two types of data to create the model","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topography\nEarthquake locations","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We start with loading the required packages","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"using GeophysicalModelGenerator, JLD2\nusing GMT","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you managed to install GMT on your machine, you can automatically download the topography with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo = ImportTopo(lon = [-18.7, -17.1], lat=[28.0, 29.2], file=\"@earth_relief_03s.grd\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In case you did not manage that, we have prepared a JLD2 file here. Download it, and doublecheck that you are in the same directory as the data file with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"pwd()","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"\"/Users/kausb/.julia/dev/GeophysicalModelGenerator/docs/src/scripts\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Load the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo=load(\"Topo_LaPalma.jld2\",\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (1921, 1441, 1)\n lon ϵ [ 341.3 : 342.9]\n lat ϵ [ 28.0 : 29.2]\n depth ϵ [ -4.38297802734375 km : 2.414 km]\n fields: (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, lets load the seismicity. We have prepared a file with earthquake locations up to early November (from https://www.ign.es/web/ign/portal/vlc-catalogo). Download that here","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"data_all_EQ = load(\"EQ_Data.jld2\",\"data_all_EQ\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"GeoData \n size : (6045,)\n lon ϵ [ -18.0341 : -17.6671]\n lat ϵ [ 28.3102 : 28.8144]\n depth ϵ [ NaN km : NaN km]\n fields: (:Magnitude, :TimeSinceJan1_2021)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write the data to paraview with","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(data_all_EQ,\"data_all_EQ\",PointsData=true)\nWrite_Paraview(Topo,\"Topo\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: data_all_EQ.vtu\nSaved file: Topo.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"As earthquakes are point-wise data, you have to specify this. (Image: LaPalma_EQTopo_GeoData) Note that this data is not in \"easy\" coordinates (see coordinate axis in the plot, where z is not pointing upwards).","category":"page"},{"location":"man/LaPalma_example/#.-Convert-data","page":"Generating LaMEM model","title":"2. Convert data","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In order to create model setups, it is helpful to first transfer the data to Cartesian. This requires us to first determine a projection point, that is fixed. Often, it is helpful to use the center of the topography for this. In the present example, we will center the model around La Palma itself:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"proj = ProjectionPoint(Lon=-17.84, Lat=28.56)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ProjectionPoint(28.56, -17.84, 222158.69478000276, 3.1625327286383654e6, 28, true)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Once this is done you can convert the topographic data to the cartesian reference frame","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"EQ_cart = Convert2CartData(data_all_EQ, proj);\nTopo_cart = Convert2CartData(Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (1921, 1441, 1)\n x ϵ [ -86.09445705828863 km : 73.67229892155609 km]\n y ϵ [ -63.5531883197492 km : 73.28446155584604 km]\n z ϵ [ -4.38297802734375 km : 2.414 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"It is important to realize that the cartesian coordinates of the topographic grid is no longer strictly orthogonal after this conversion. You don't notice that in the current example, as the model domain is rather small. In other cases, however, this is quite substantial (e.g., India-Asia collision zone). LaMEM needs an orthogonal grid of topography, which we can create with:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = CartData(XYZGrid(-70:.2:70,-60:.2:70,0));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, the routine ProjectCartData projects a GeoData structure to a CartData struct","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Topo_LaMEM = ProjectCartData(Topo_LaMEM, Topo, proj)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"CartData \n size : (701, 651, 1)\n x ϵ [ -70.0 km : 70.0 km]\n y ϵ [ -60.0 km : 70.0 km]\n z ϵ [ -4.29541702331831 km : 2.3840784607152257 km]\n fields : (:Topography,)\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Let's have a look at the data:","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Write_Paraview(EQ_cart,\"EQ_cart\",PointsData=true)\nWrite_Paraview(Topo_LaMEM,\"Topo_LaMEM\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: EQ_cart.vtu\nSaved file: Topo_LaMEM.vts\n","category":"page"},{"location":"man/LaPalma_example/#.-Create-LaMEM-setup","page":"Generating LaMEM model","title":"3. Create LaMEM setup","text":"","category":"section"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step, we need to read the LaMEM input file of the simulation. In particular, this will read the lateral dimensions of the grid and the number of control volumes (elements), you want to apply in every direction. The LaMEM input file can be downloaded here. Make sure you are in the same directory as the *.dat file & execute the following command","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Grid = ReadLaMEM_InputFile(\"LaPalma.dat\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"LaMEM Grid: \n nel : (64, 64, 32)\n marker/cell : (3, 3, 3)\n markers : (192, 192, 192)\n x ϵ [-50.0 : 50.0]\n y ϵ [-40.0 : 40.0]\n z ϵ [-80.0 : 15.0]\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The LaMEM_grid structure contains the number of elements in every direction and the number of markers in every cell. It also contains Grid.X, Grid.Y, Grid.Z, which are the coordinates of each of the markers in the 3 directions.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In a next step we need to give each of these points a Phase number (which is an integer, that indicates the type of the rock that point has), as well as the temperature (in Celcius).","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Phases = ones(Int32,size(Grid.X))*2;\nTemp = ones(Float64,size(Grid.X));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"In this example we set the temperature based on the depth, assuming a constant geotherm. Depth is given in kilometers","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Geotherm = 30;\nTemp = -Grid.Z.*Geotherm;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Since we are in La Palma, we assume that temperatures are not less than 20 degrees. Moreover, in the mantle, we have the mantle adiabat (1350 C)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Temp[Temp.<20] .= 20;\nTemp[Temp.>1350] .= 1350;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Because of lacking data, we have pretty much no idea where the Moho is in La Palma. Somewhat arbitrary, we assume it to be at 40 km depth, and set the rocks below that to \"mantle\":","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( Grid.Z .< -40);\nPhases[ind] .= 3;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Everything above the free surface is assumed to be \"air\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = AboveSurface(Grid, Topo_cart);\nPhases[ind] .= 0;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And all \"air\" points that are below sea-level becomes \"water\"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"ind = findall( (Phases.==0) .& (Grid.Z .< 0));\nPhases[ind] .= 1;\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"You can interpret the seismicity in different ways. If you assume that there are fully molten magma chambers, there should be no earthquakes within the magma chamber (as stresses are liklely to be very small). If, however, this is a partially molten mush, extraction of melt of that mush will change the fluid pressure and may thus release build-up stresses. We will assume the second option in our model setup.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Looking at the seismicity, there is a swarm at around 35 km depth","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddSphere!(Phases,Temp,Grid, cen=(0,0,-35), radius=5, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"A shallower one exists as well","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-1,0,-11), axes=(3,3,8), StrikeAngle=225, DipAngle=45, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"And there might be a mid-crustal one","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"AddEllipsoid!(Phases,Temp,Grid, cen=(-0,0,-23), axes=(8,8,2), StrikeAngle=0, DipAngle=0, phase=ConstantPhase(5), T=ConstantTemp(1200));\nnothing #hide","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can generate a 3D model setup, which must include the Phases and Temp arrays","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Model3D = CartData(Grid, (Phases=Phases,Temp=Temp))\nWrite_Paraview(Model3D,\"Model3D\")","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Saved file: Model3D.vts\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"The model setup looks like this (Image: LaMEM_ModelSetup_LaPalma)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"We can create a LaMEM marker file from the Model3D setup and the (cartesian) topography","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Save_LaMEMTopography(Topo_cart, \"Topography.txt\")\nSave_LaMEMMarkersParallel(Model3D)","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Written LaMEM topography file: Topography.txt\nWriting LaMEM marker file -> ./markers/mdb.00000000.dat\n","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"Next, you can use this to run the LaMEM model and visualize the model results in Paraview as well. If you are interested in doing this, have a look at the LaMEM wiki pages.","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"","category":"page"},{"location":"man/LaPalma_example/","page":"Generating LaMEM model","title":"Generating LaMEM model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = GeophysicalModelGenerator","category":"page"},{"location":"#GeophysicalModelGenerator","page":"Home","title":"GeophysicalModelGenerator","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Documentation for GeophysicalModelGenerator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The main purpose of this package is to simplify the process of going from 1D/2D/3D geophysical data to a 3D consistent model of the region. By simplifying the process of plotting the data, it becomes easier to compare different data sets, and generate a 3D models that can be used for other computations such as geodynamic simulations, or forward modelling of gravity anomalies.","category":"page"},{"location":"","page":"Home","title":"Home","text":"For this, GeophysicalModelGenerator provides the following functionality:","category":"page"},{"location":"","page":"Home","title":"Home","text":"A consistent GeoData structure, that holds the data along with lon/lat/depth information. \nRoutines to generate VTK files from the GeoData structure in order to visualize results in Paraview.\nThe ability to deal with points, 2D profiles and 3D volumes, for both scalar and vector values.\nRapidly import screenshots of published papers and compare them with other data sets in 3D using paraview.\nCreate movies for representation of earthquake or wave propagation.\nCreate geodynamic input models (for LaMEM)","category":"page"},{"location":"","page":"Home","title":"Home","text":"The best way to get started is to look at the tutorials.","category":"page"},{"location":"man/tutorial_ISC_data/#Plot-ISC-earthquake-data","page":"ISC earthquake data","title":"Plot ISC earthquake data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#Goal","page":"ISC earthquake data","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"This explains how to load earthquake data obtained from the ISC catalogue.","category":"page"},{"location":"man/tutorial_ISC_data/#Steps","page":"ISC earthquake data","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_ISC_data/#.-Download-data","page":"ISC earthquake data","title":"1. Download data","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"You can get data from the ISC catalogue here: http://www.isc.ac.uk/iscbulletin/search/catalogue/ The catalogue will give you an on screen CSV output that will then have to be copied to a file of your choice (here we will call it ISC1.dat). Do that and start julia from the directory where it was downloaded.","category":"page"},{"location":"man/tutorial_ISC_data/#.-Read-data-into-Julia","page":"ISC earthquake data","title":"2. Read data into Julia","text":"","category":"section"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The main data-file, ISC1.dat, has 23 lines of comments (indicated with #), after which the data starts. We can use the julia package https://github.com/JuliaData/CSV.jl to read in the data, and tell it that the data is seperated by ,.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> using CSV, GeophysicalModelGenerator\njulia> data_file = CSV.File(\"ISC1.dat\",datarow=24,header=false,delim=',')","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"As this data contains a lot of information that we are not interested in at the moment and which is given in non-numeric fomats (e.g. date, time etc.), we will use our helper function ParseColumnsCSVFile to only extract columns with numeric data.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> data = ParseColumns_CSV_File(data_file, 14)\njulia> lon = data[:,2];\njulia> lat = data[:,1];\njulia> depth = -1* data[:,3];\njulia> magnitude = data[:,4];","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"Converting this data to a GeoStruct data and to export is to Paraview is then straightforward.","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"julia> EQ_Data = GeoData(lon,lat,depth,(Magnitude=magnitude,Depth=depth));\njulia> Write_Paraview(EQ_Data, \"EQ_ISC\", PointsData=true)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"The result the looks like this (plotted here together with the topography):","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"(Image: Tutorial_ISC)","category":"page"},{"location":"man/tutorial_ISC_data/","page":"ISC earthquake data","title":"ISC earthquake data","text":"In case you are interested: we are employing the oleron scientific colormap from Fabio Crameri's scientific colormap package here.","category":"page"},{"location":"man/tutorial_Coastlines/#Add-coastlines","page":"Coastlines","title":"Add coastlines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#Goal","page":"Coastlines","title":"Goal","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"For orientation, it is often nice to add country borders and coastlines to your paraview plots. ","category":"page"},{"location":"man/tutorial_Coastlines/#Steps","page":"Coastlines","title":"Steps","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.-Coast-lines","page":"Coastlines","title":"1. Coast lines","text":"","category":"section"},{"location":"man/tutorial_Coastlines/#.1-Download-land/sea-data","page":"Coastlines","title":"1.1 Download land/sea data","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The package GeoDatasets.jl has a simple interface to get a grid that explains whether the Earth surface is land, sea or a lake.","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> using GeoDatasets\njulia> lon,lat,data = GeoDatasets.landseamask(;resolution='l',grid=1.25);\njulia> ind_lon = findall( (lon .> 0) .& (lon .< 30 ) );\njulia> ind_lat = findall( (lat .> 35) .& (lat .< 50 ) );","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The parameter resolution should be either c,l,i,h or f (standing for crude, low, intermediate, high and full resolution)","category":"page"},{"location":"man/tutorial_Coastlines/#.2-Save-in-Paraview","page":"Coastlines","title":"1.2 Save in Paraview","text":"","category":"section"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"julia> Lon,Lat,Depth = LonLatDepthGrid(lon[ind_lon],lat[ind_lat],0km);\njulia> data_surf = zeros(size(Lon));\njulia> data_surf[:,:,1] = data[ind_lon,ind_lat]\njulia> data_surface = GeoData(Lon, Lat, Depth, (SurfaceType=data_surf,))\njulia> Write_Paraview(data_surface, \"ContinentOcean\") ","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"The result is shown here, together with Moho data","category":"page"},{"location":"man/tutorial_Coastlines/","page":"Coastlines","title":"Coastlines","text":"(Image: Tutorial_Coastlines)","category":"page"}]
+}
diff --git a/v0.4.8/siteinfo.js b/v0.4.8/siteinfo.js
new file mode 100644
index 00000000..e15fea6a
--- /dev/null
+++ b/v0.4.8/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "v0.4.8";
diff --git a/versions.js b/versions.js
new file mode 100644
index 00000000..a9cb80a5
--- /dev/null
+++ b/versions.js
@@ -0,0 +1,9 @@
+var DOC_VERSIONS = [
+ "stable",
+ "v0.4",
+ "v0.3",
+ "v0.2",
+ "dev",
+];
+var DOCUMENTER_NEWEST = "v0.4.8";
+var DOCUMENTER_STABLE = "stable";