 just put a couple slides before we get into the notebook. So this is a project that I've been working with as part of a larger project looking at landscape evolution in the Colorado Front Range. And this is a little aspect that's developed out of that of thinking about what happens when you start thinking about feedbacks between the hydrology and the geomorphology which produce a heterogeneous surface where you have exposed bedrock in some places and soils, relatively thin soils in other places. And this is like I said in collaboration with Greg and Suzanne and Bob. And I want to just, you know, Greg kind of already went through this but from the kind of geomorphic view that one of the simplest visions we have is this kind of characteristic parabolic form to hill slopes. This is just a view out of my my brother and his house in his backyard, right? And so when we start thinking about simple models, there's two simple models that we can bring in right into land lab or components in land lab that basically are just solving for mass balance between the flux downslope and the conversion of bedrock to soil. And so one of those is the kind of creep model that Greg had in his notebook and it's just saying that, you know, there's a linear dependence with slope in the sediment flocks and that's what gives us our parabolic form. And then oftentimes, and this is based partially on observations, it's partially on empirical measurements of soil production rates, we fit something like this is an exponential soil production function. Sometimes people argue for a humped one where it goes down to zero with that zero bedrock. But these are basically two core components that a geomorphologist, if they have soil and they have the surface might include. But what happens when you go to hillsides like this, so this is just the image I took near Gold Hill, Colorado up in the four mile watershed. It's actually in the scar of the four mile wildfire. And you can see it's very heterogeneous. There's in the background, you see steep bedrock cliffs. In the foreground, you see some bedrock tours. And you see relatively thin soils that are kind of dispersed in between. And so the goal that I have is can we replace this kind of general soil production, generic soil production function with something that is more process specific. And in particular, I've been experimenting with processes that might be conducive towards an agent based model. I'm going to think about trees. I'm going to share with you a little bit of my thoughts on trees. There's lots of things we might consider with trees when it comes to soil production. This is just a conceptual figure from a paper and review paper in 2013. I'm really only going to focus on kind of what the biomechanical weathering component of tree roots might have on producing soil, right? So we might think that roots grow to a certain depth, they grow to a certain rate. So we can actually relate that tree property to a soil production rate in an actual landscape. And this is really kind of building off the backs of other kinds of models that are similar in spirit, albeit not using an agent based model. So these papers back in the mud and roaring at all, including Jill here who's here with us today. And I just want to give you a brief, instead of the net locale model is there for you that I developed, or I should say a simple version of the one I developed is there for you in the repository. But I thought I'd just give you a conceptual model of what's actually going on in this agent based model. Our agents are trees. They're basically borne by seeds. So they have some seed production. They have some seed fertility. They have some seed dispersal properties. And then there's some, when they live, they have an area. So the red domain here is basically the patches on this kind of cartoon grid where they might have resource competition. So you can imagine that their growth rate shouldn't just be some simple plant functional type function, but it has to have some sort of resource competition associated with it. So there's a neighborhood that matters. And this is where the agent based modeling is well suited to it. And this is quantified through this term that I use. It's just a resource stress term that allows the resource stress can alter the growth rate. It can alter the fertility. It can alter the death rate. And then the idea here is that the only mechanism to produce soil in this model is through trees interacting, getting their roots down to the bedrock soil interface. So if trees start growing in places where there's already soil, then they just grow happily in that soil. But as soon as their roots come in contact with the interface of bedrock and soil, then they can start converting bedrock into soil. And so this is only, like I said at the beginning, only one potential role trees play, but it could be a potentially important one. I'm interested to see how these dynamics may play out with our more simpler models of soil production. And so basic framework, net logo, I'm going to use to simulate the forest dynamics and the soil production. And I'm going to use land lab to simulate the erosion and sediment transport. So there's both the kind of vertical loss of soil and that then being spread out across the landscape. So we might expect different results if we actually have a proper transport model. And to give you, for those of you who are familiar with net logo, I've kind of listed out all the variables that are in the model on the right-hand side. You can kind of just look at the left-hand side. There's basically three basic categories of things going on in the model. There's the trees, the individual tree, the forest dynamics. Those are in turtle in the net logo parlance. Those are the turtles in my model. And then there's the patches in my model, which are carrying states like soil depth, elevation, things like that. And those patches are what I'm going to actually use to link with my land lab model, which is modeling the soil erosion transport, with a variety of potential feedbacks. In fact, the version that you guys have is a simpler version. So some of these feedbacks are going to disappear. But you can imagine, we can add as many of these feedbacks as we might want. And all the bolded text that I put on that right-hand side, those are just inputs. So those are things that we can now start playing with, you know, what is the dispersal distance, characteristic dispersal distance of trees? What is the maximum rooting depth of a given plant functional type? So we can start evaluating the sensitivity of these different things. And then the key thing is that I'm using Pinet logo to link the two, as opposed to building it all on a Python environment. Before you get started, I just want to ask a technical question. My Pinet logo doesn't load because I don't have something called Jpyte. JPYPE. Does that ring a bell to anybody out there? I ran into the same problem. It's whether you... So in the documentation, it'll take you to how to install the Java stuff, but I still ran into problems with what directory the Java was in. But that's what it's referring to. And it's one more step in the installation instruction. Yeah. So it is in the Pinet logo documentation and the Java issues are real. And also the version of NetLogo you have is real. So if you have the latest version of NetLogo, it will not work. Oh. Well, that fixes that. So I do. Yeah. So in the notebook, I have some comments to that effect. Basically, it works with 6.0 and not 6.1. So hopefully, I had to learn that the hard way myself as I was learning this. And then the documentation proved and said, oh, we don't support 6.1 yet. So be forewarned. Oh, that makes you do so much better. Yeah. No, I struggled through that myself. I was like, I think I'm doing everything right. But it turns out that it's just not supporting the newest version. So any of the versions of 5, NetLogo 5, it will work with. And 6.0, it will work with. And hopefully, they're working towards getting to work with 6.1. The final little, sorry, is there any other questions that popped up? Sorry. Thank you. No, no problem. The final piece is that I have a bunch of these slides. I'm not going to show them. I don't think I'm going to show them until the end. I want to get to the notebook first. But one instinct or insight that can be gleaned right away before going out and trying to link a landscape evolution model with this forest dynamics model is that simply adding some lost term like erosion means that this interesting question from the geomorphology community is that we can actually produce steady state landscapes that have a heterogeneous bedrock to soil cover ratio. And so this is all done in NetLogo. I did here is just I'm plotting up soil fraction as the function of time for a given set of input parameters and showing you that it does obtain a steady state soil fraction scenario for different values of erosion rate. If I only allow erosion to happen in the soil. And so I have a few other like sensitivity plots I might show to you guys at the end. But this was what gave me pause and say, OK, now we need to stick an actual proper sediment transport model because how robust are these kinds of results that I'm kind of hacking into a NetLogo model? All right. I'm going to switch now to the notebook. Let's see. I'll share that at the right one. All right. Do you guys all see my notebook? Yeah. Yes. Yes. All right. Perfect. So there's the model. I'm going to leave that as a black box right now. It's a little model I developed with all those components in it. And now I'm just going to show you how we can couple something simple like the linear diffusion style model that Greg was showing to iterate through letting the forest evolve and then diffusing the landscape. A couple of things about this notebook, if you're trying to write it here, it says right at the beginning, you need 6.0, not 6.1 is that first thing. You need this model, obviously. So this is how you would call any sort of model if you want to start bringing it in. In this case, you just keep it in the local directory. I am using the Seaborn library for data visualization here. So and I've also added this thing where there's a CSV file. I'm sorry, I didn't update this. Or you can use an Excel file. This is a weight. So in that logo, it's very easy to see the random number of agents. This takes, you can just impose where you put agents in R in the model so that when you're running it, you always have the same initial condition. So it's not required to run this notebook. But if you want to compare plots as we go through, it'll be easier. Just look at kind of apples to apples. So at the beginning here, we're just going to import all the packages we need from LandLab and from Matplotlib. One thing to note, and I'll say this below, but Pinet logo basically brings in grids as pandas data frames. So you need to deal with converting them over from pandas data frames into the grids that are used in LandLab. So let me just run this. I'm going to open NetLogo here. I strongly encourage you to set this GUI flag to false. Things run tremendously faster if you're not actually using, doing all your visualization in Python is really, really handy. And then here, I just have a check for the version just to make sure you meet that condition of having an acceptable version for Pinet logo. I've stuck this figure in that is just like the figure I showed in the PowerPoint, only it's showing you which elements of complexity I've removed, right? So I've got strike-throughs on all the pieces that I took out of this simpler version of that logo, right? So we've gotten rid of some of the potential feedbacks, but it'll at least illustrate to us how we can pass grids back and forth and we still get some pretty interesting dynamics out of it. So one of the nice things about using Pinet logo is that you can take your knowledge of the syntax of NetLogo and you basically just stick it into these command prompts. So this first, the cell here right below part one is really just saying, I want to command NetLogo to do a bunch of things and all these strings are just telling you how to, those are in the NetLogo syntax. So in this case, I'm just setting up, I'm loading the model and I'm setting up all of these parameters that are important, like the initial number of trees, the tree root max, the tree age max, seed max, the seed dispersal, and the seed decontinue. And then once I do that, I can set up the model, right? Take a second. And then this is this optional cell I was telling you about. So this is just the piece where if you want to stick in a CSV file or an Excel file that has the initial position of all your agents, this is, it's really simple. You can just bring it in as a PANAS data frame and you can, you know, you can check it out. We'll map it out real quickly. I set the initial coordinates of four trees that are equally spaced apart from each other throughout the model domain. And so we can go ahead and map that out. So we're going to, the first part here, we're going to report where all those trees are from NetLogo. And then we're going to also get this NetLogo.report. We're going to pull some of the constants that are buried within the NetLogo model because I want to show you some relationships that are implied by using this model. And then we're just going to make a figure. And this figure on the left-hand side, I'm going to go ahead and run it. On the left-hand side, I'm just going to show you where the initial tree locations are. And on the right-hand side, I'm going to show you what my root function actually looks like in the model. So it's just telling you that in this version of the model, I've specified the age of the trees. They have a lifespan. I don't have them dying before the end of their lifespan. So another version I do. So in this case, I'll live to 100 years and that they, their roots will grow initially very fast, which is based on the published literature around root growth dynamics. And it reaches some maximum value at the end of its life and it slows down. So the root growth slows down with age. Now, I also have this term, this is this resource availability term that is in my case encapsulating resource competition from neighbors. But you could imagine using it also to capture variable climate, variable rock soils types. So you could use this resource term to actually affect the dynamics a lot. And what you're seeing is that if I have a value of this weight of one that I grow on my maximum trajectory and then anything less than that, I grow at a slower rate. The actual trajectory of trees doesn't look like these simple curves because during their lifespan, there are new trees that are being born and old trees that are dying. So their trajectories are jumping on and off of different versions of these curves. And so like before, we're going to use this patch report. So this is another function. There's only less than a dozen functions really within PyNet logo, but they're all very powerful because they allow you to basically either get information from that logo or modify things that are in that logo. So in this case, we're going to report all the elevations. I set it up so that I actually in dealing with elevation, the initial condition in that logo, you could do it either way. So here I'm going to report my elevations, I'm going to report my initial soil depths, and then I'm just going to plot them up. So here we go. So I'm starting from the initial condition where there's zero soil depth. So this right hand side is good. It means it worked. There's no soil anywhere. When I start the model, I set up a ramp of around 36 degrees, basically going from the north to the south, pretty similar to the setup that Greg had in his example. And now we can go ahead and run the model. So when we run the model, you have to give it some time, number of time steps to go through. So this is something in, we talked about earlier, you have to think very carefully about, especially as we start coupling them, because you want to make sure those time steps make sense. And we're going to report back the locations of all the new trees that are produced in the model. So the second bundle is telling us. And then we're going to report back all the resultant soil depths and plot them up. So let's go ahead, run it. It shouldn't take too long. And unsurprisingly, I set them up so they're equally apart. So we have these four little clusters of trees. Notice that the original trees are gone. And so the legacy of those other trees is in the soils, not in the current locations of trees. One of the very important parameters in this model is the dispersal distance. So if you have a very short dispersal distance, then you can set, in this particular model, the forest can go extinct. It can die because they can't get outside the resource competition. If you set the dispersal distance very wide, it's like having random seed generation all across the landscape. So I have a pretty tight dispersal distance here. So you're going to see these clusters, makes it easier for us to see these clusters as they grow through time. And then the other thing we can look about is we can, we can use Pinot logo to start looking at attributes about our agents and then using all the power of the statistical packages and plotting packages in Python to interpret them. So it's really nice because in this particular example I'm going to show you, I'm going to report back the age of the trees. I'm going to report back the soil depths and report back the soil fraction and then just plot them up as histograms. And so, you know, we didn't run our model for very long. In general, this distribution of tree ages, if I don't put a resource depth on these trees, it basically will bounce around where you see equal distribution at all ages, right? So there's just as many trees dying at any given time as they're born at any time. Now, we ran it for a pretty short time. So we're really sensitive to the initial conditions that we have. And then we can also plot up. We see we got to have a distribution of soil depths. I just want to point out, in this particular version, I have a maximum soil depth of three meters. It is very rare to produce an actual soil of three meters because they're all competing with each other. And so there's being scales of the rare tree that gets outside the patches that can grow for its entire life at that maximum rate. So you're seeing most of our trees in this particular example, I should say most of our trees had grown only to soil depths of around half a meter, right? So we get this very skewed distribution. And again, that's because we have this resource competition. And so this is just, this first example was just meant to show that you can drive everything in NetLogo within a Python interface. And there's some really, I should stop here and say there's some really nice tutorials on PinetLogo where they do a nice job of showing how you might do a sensitivity analysis. So if you wanted to paralyze your NetLogo runs so that you have a bunch of different runs and you want to do the statistics on it, it's a way more efficient way to do that than trying to work within NetLogo itself. Or at least I should say you have the full advantage of all the Python packages that exist to do those things. So running a headless version of NetLogo pretty straightforward. There's just a couple different kinds of commands you would use, these report commands and these set commands in order to do that. So in the second example, I'm just going to, I have basically three parts. The second part, I'm simply going to do one time step at a time, one bulk time step at a time. I'm going to run NetLogo. I'm going to run LandLab. And then I'm going to run NetLogo again just to make sure that I'm passing things back and forth. And the final example is actually just bundling all it up into a for loop to see what that might do over longer timescales. So let's talk about passing variables between NetLogo and LandLab. I'll stop right here for any questions or comments. So this works very much like our NetLogo as far as I can tell. I don't know if you've used that or not, but where you have our primitives that you just plug in within your R script to do stuff. In fact, I think in the documentation of PinetLogo, they've taken their inspiration from our NetLogo. So it's exactly, I think you're exactly right. It has the same Java problems that our NetLogo does too. Okay. So linear diffusion or soil creep is actually a relatively straightforward thing to implement in NetLogo. So if I were only doing that, I actually think it would be just as easy for me to do that in NetLogo. I think the real advantage of bringing it into LandLab at this stage is that there's four different possibilities we might want to use for our diffuser. We might have a linear diffusion model, a nonlinear diffusion model, a depth dependent diffusion model, right? We have all these components that are already packaged and ready to go for being in the LandLab interface. And so really that's where the power of it comes. And so that's what this is all with an eye towards. We're going to basically do our sensitivity analysis on all these different variants of alternative hill slope sediment transport models. Today, I'm just going to show you the simple case using linear diffusion. So in this first cell, I'm going to reinitialize the model. So because I've already set up all my inputs, and you could set this up with the text file too, I'm just going to reset it up to that initial condition. And the second patch here is just telling me I want to read it in from that CSV file for the initial conditions again. The one new thing that I'm doing here is now I will also want to set up my LandLab grid at the same time so that it matches, right? We need these grids to conform to each other. So the sizes and the dimensionality of the grids need to be the same. And like I was saying before, PinetLogo brings these things as pandas data frames. So all I'm doing here in these second two steps here in the cell is setting up my LandLab grid with what my patches represent, a DX, a total time that I'm going to run. So this time I'm going to run a thousand ticks, which my functions are kind of set for a yearly time. So that represents like a thousand years. And then I have to set this similar to the way Greg dealt with diffusion, having this depth-dependent diffusion so that you didn't have production of soil on very thin soils that wasn't due to the processes we care about. So I'm going to set that characteristic depth of diffusion. And then this is just setting up my initial LandLab grid with its boundary conditions. And very similar to what Greg showed before. So I should forget if I ran this. It doesn't matter. I can rerun this as many times I want because we're starting from scratch here. And then I'm going to add some fields. So in this case I'm going to add a topographic elevation field, a past elevation field, a soil cover field, and a soil depth field. And I really should rename the soil cover field. It's actually my diffusion coefficient field because I'm using it to modify the diffusivity as a function of soil depth. Okay, so that's very straightforward. Let's run NetLogo and send the values to LandLab. So we have to give NetLogo a command it recognizes. And in this case I've just said it kind of so that I can have any time I will just send it to this go command. And then I just send NetLogo command go. And then I have to when I report the elevations and pass them to LandLab, I need to convert them to the size that LandLab is expecting. So that's what all these little things are doing. I'm just reporting the elevation passing the LandLab by reshaping it. Same with the soil depths. And then I'm calculating this diffusion coefficient field based upon the depths. Now this is exactly like what Greg showed. He had one minus this exponential. I put 1.0001. And it's because if I have a zero diffusion coefficient, it raises lots of errors in your linear diffuser. So basically this is effectively like saying I have a diffusion coefficient that's 10,000 times slower than the maximum value I'm using for places that have soil. So it's a very, very slow. It's actually an extra source term for sediment in the way that I'm doing the model. But it's very small with respect to the soil depth. And then I'm also going to print out the mean depth for comparison later. So this will tell us how much soil is being produced. And it also tell us, kind of help us keep track as we redistribute soil. Are we doing anything weird by moving soil around by the way we've set our diffusion model itself? So let's run it pretty fast. 1,000 years runs pretty good. We're going to see when we do. Go ahead. So the question, I mean, it looks like you're just running NetLog. You've set it up. Then you're just going to run NetLogo for 1,000 years. But it was not without anything. So I was wondering if maybe you're going to do this later. I thought maybe you'd want to step, you know, one year through NetLogo and then do LandLab and step through NetLogo. Yeah. So in the for loop, I'm going to put steps in. So I just want to show that we can pass these variables back and forth. That's going to be really important, right? This gets us sensitive. What are the right time steps to choose? Because do I want to do NetLogo at an annual time step? Because that's going to be really computationally expensive. Or in the example I show, I do the half-life of a tree. So every 50 years I run NetLogo and I re-diffuse the landscape. So I'll show that in the for loop. Okay. So we've run it in NetLogo and so we're ready to redistribute the soil. So much like Greg showed, I'm just going to initialize the diffusion component. And then all I'm doing is I'm going to keep my elevations from this step. And I'm going to record them in what I'm calling this ZP, which is the prior Z. And then I'm going to diffuse the landscape and then I'm going to recalculate the soil. So that's all I'm doing here. So let's go ahead and do that. And now we can make the same figures we made with the initial conditions, exactly the same plotting functions here. And we can look what we get. So we now have this kind of patchy soil that is inherited the initial condition. And you can see we get this droopy diffusive landscape, right? So there's lots of these little kind of droops that are correlated with where we've actually had trees. So it looks very linear, like we would expect for linear diffusion in the places where the trees haven't made it to yet. So that makes good sense with what we're thinking. And we look at our mean depth, 0.052 because we had 0.052 before. So we're not like doing anything weird with the soil depths here. We're preserving the soil. We're just moving it around. And then the other thing I want to show you is I'm just going to do another figure that shows how the elevations have changed with respect to the initial condition. So I just run that. And the initial condition is this red line. And you can see I have places where I've accumulated soil. I have places where I've eroded soil. And in this particular case, because of the way I set up that initial condition, it's concentrated kind of in these two quarters of the, you know, in the middle of the landscape, it looks just like the initial condition. But you can see stuff is marching its way downhill. And I'm going to go real fast to this part because there's not much new here. The only thing that's new is I now have to take that elevation data and send it back to net logos. It means I need to put it back into a data, pandas data frame. And I'm going to do that using pandas. And I'm going to then use the pie net logo dot patch set to reset that the elevations in the depths. I'm going to go ahead and run it quick moment. Okay. And just plot it up again. Now, this is just a check for me. In this version of my net logo model, I don't have any feedback between the elevation and it's only a one way feedback, right? So elevation is getting modified in land lab, but not net logo. So my elevation should look exactly the same because I haven't sent it back to land lab. But if we compare our soil depth, we can see we produced a lot more soil now. So you can just see this is the style of step we would run. And then I'm almost done here. I guess the only thing I'll say here is this is exactly what Michael's bringing up. We don't want to run this for a thousand years of forest dynamics. And then defusal landscape, we would want to set some time step that makes sense. So I've set the land lab time step here to be 50 years, which in this case is half of the average lifespan of a tree. I'm going to run it for much longer. Everything else is the same. That's just setting up the initial conditions. And this is everything I had in the previous parts. Just highlight this, except I've just bundled it up into a for loop. So we're just going to run it for the range of time and see what we get. Now, it'll take a few minutes to run. So I guess it would be a good time to bring any questions out. So you're playing with an oak command on this, unless you've defined go. I mean, normally go is a loop in NetLogo. But you can also do a one shot. I guess you're just running go once, right? Yeah. And this is, to be clear, this go that the variable go, perhaps I should rename it, it's not the same as the go command in NetLogo. I've defined the whole string as go. So I set what that time step is by defining the string up above. So in this case, by me putting my dt of equal to 50, it's running go for 50 time step. Got it. Got it. Okay. Yeah. And just constructing that string dynamically so I can monkey around with it. Okay. Any other questions while we're waiting for this? So I have a question. So what do you think? What do you think is going to happen if we run? So if we go back to what it looked like after this was after 1000 years, but not iterated, we're now going to run it. We're now running it in 4000 years, but it's iterating over much shorter time steps. So I'm curious, what do you think is going to happen to the topography? How's it going to look different? Or will it look different? I'm excited to see some clustering. You see some clustering? Okay. Thanks for sharing this stuff. Yeah, of course. Much appreciated. Other ideas? How are we doing? Will there be net erosion over that time? Well, so the way, so this is really important how you set your boundary conditions and, you know, in this case, I'm not uplifting the landscape, but I have a closed boundary condition at the top of the model domain. So it means that there's no input from the top. So stuff is just trundling downhill. And that's, you know, kind of a match. And there's no accident at the bottom? Well, it is. The bottom is held constant. So it's effectively like having an open boundary condition at the bottom. Yeah, I thought there was. So that's why I was thinking it would overall, there would be some degradation. Right. So if I add uplift, you might expect that it could evolve towards some steady state. In this case, we might expect, if we're just doing diffusion, it would start relaxing down because I'm just holding this at a constant elevation. That's what I meant. So it would decrease. There would be some net loss. Yeah, exactly. Okay, so you would expect that. Okay. Yeah, exactly. Yeah, and we're only running this for 4,000 years. So let's run it. Let's plot up what we see. It's okay. So one thing I'll point out is, and it's a little hard to see, it's hard to find good color ramps to show this, but you get these little pockets of, I would call them Torah-like features where they're kind of, they get abandoned and there still seem to be on the landscape. But because we ran it for a long time and because we iterated through shorter time steps, we get a much smoother landscape, looks a lot more like a diffusive landscape. And of course, we've allowed more soil formation to happen. We started with no soil, allowed more time. So it means that more of the landscape has been covered. But even after 4,000 years, there's a lot of places with zero soil depth. So it's telling us that it takes a long time for this particular mechanism, given this particular configuration to actually produce soil all across the landscape. And so maybe an easier way to show this is to plot up that same initial condition versus the current condition. And hopefully the thing you see with this is that I printed out the mean elevation. So this is to Mary's point. We've actually got net erosion, which is good. So it's behaving in a way that makes good sense. It used to be 142. Our initial condition was like 142. And we see the same kind of like bouncing around that initial condition, but it's getting a lot tighter. And it's getting a lot tighter around that initial condition, because places that are have bedrock exposed are trapping soil from uphill. And therefore, you're smoothing out the landscape. But at the top of the landscape, we're getting something that looks more like our parabolic top, right? But notice, and it's again, very hard to see, even on this parabolic top, there are these places, these individual patches that are getting abandoned. Because if they can't get, if they can't stay contiguous with the soil that's fluxing downhill, then they will get abandoned because they never have, if there's nothing flowing into them, they're never going to get new soil until you randomly get a plant up there. So they can stick around for a very long time, even though you're smoothing out the landscape. And then finally, we can get a cleaner, a cleaner look at the distributions that we looked at at the beginning. So we now get cleaner distribution is look at, yeah, we get something like equal chance of all elevations and again, a very skewed soil depth distribution. But even if we run for a long time, we don't get very deep soils. And that's because we have resource competition going on here. So I'll stop there because I've talked a lot. But I thought I'd open up for comments and questions. There's not very many feedbacks that we've included in this one, but it's still quite interesting. Now, one thing I think is really interesting about this is that you get very smooth terrain, but really bumpy depth to bedrock, your soil depth is very heterogeneous. It doesn't get smoothed out. That's right. And that's because, and part of this is the paired thing to do with the start with the initial condition of some soil that could be lost as opposed to starting with zero soil. So it takes a long time. I'll just show one other thing very quickly. Let's stop here. This is just back to that PowerPoint. Sorry, I should have advanced this. So this time scale of which, even if you had no erosion, so that's what these plots are showing is there's no erosion. This is just a net logo model looking at the kinds of time scales and their sensitivity to these different input parameters is pretty long. So for me to cover the entire landscape with just this mechanism of soil production, it's taking on order thousands to tens of thousands of years depending upon the input parameters I put for the tree dynamics. So I'll just stop there, but that's why you're still preserving these little nubbins. It takes a long time just to randomly occupy those places where you preserved a little tour. That's awesome. Second, that's super cool. And I have to say that your end results from the model with, as Greg was pointing out, even though you have a relatively smooth surface topography, that the soil depths are really variable, that's what we see with GPRs that we see. I've seen with a lot of field digging in similar locations. So that's great. This is awesome output. I'm curious and this is just kind of from my own personal interest. In the more complex stuff you're running, have you played around at all with where you have trees, having higher diffusion rates, or you always applying a uniform diffusion rate? So that's something I didn't talk about, but we can imagine there's two feedbacks that I'm actually explicitly trying to link to the model. One is using the density of trees to set the diffusivity constant itself. So that's a link to not only soil production, but it's a link into the diffusion. And also, in parallel, think about using that as setting the cohesion. So you can think about that from a mass placing perspective too. So if you have high root density, potentially that could stabilize these soils depending upon, again, your initial conditions, your boundary conditions, all these things. The interesting thing that I didn't show in this example is that when you add resource depth, so when you say trees don't just live for 100 years or they don't just live for 200 years, what happens is you get this selection process, this feedback in the agent-based model that enables deeper soils. So if you just looked at the soil cover over time, it looks very similar to not having that variable lifespan. But if you look at the actual soil depth distribution, it alters it quite a bit. And so there's actually some really interesting dynamics in thinking about, well, do we actually know what these functional relationships should be so that we could make a prediction of soil production that is based upon plant properties?