Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Split MountainRange into MountainRangeBasic #11

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ endif()
add_executable(mountaindiff src/mountaindiff.cpp ${COMMON_INCLUDES})

# initial
add_executable(initial src/initial.cpp ${COMMON_INCLUDES})
add_executable(initial src/initial.cpp src/MountainRangeBasic.hpp)

# mountainsolve_serial
add_executable(mountainsolve_serial src/mountainsolve.cpp ${COMMON_INCLUDES})
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The other binaries mirror those that will be built for the C++ phases of the pro

| Corresponding phase | Binary | Source files |
| --- | --- | --- |
| [Phase 1](https://byuhpc.github.io/sci-comp-course/project/phase1) | `initial` | [initial](src/initial.cpp), [MountainRange](src/MountainRange.hpp) |
| [Phase 1](https://byuhpc.github.io/sci-comp-course/project/phase1) | `initial` | [initial](src/initial.cpp), [MountainRangeBasic](src/MountainRangeBasic.hpp) |
| [Phase 2](https://byuhpc.github.io/sci-comp-course/project/phase2) | `mountainsolve_serial`* | [MountainRange](src/MountainRange.hpp) |
| [Phase 3](https://byuhpc.github.io/sci-comp-course/project/phase3) | `mountainsolve_openmp` | [MountainRange](src/MountainRange.hpp) |
| [Phase 6](https://byuhpc.github.io/sci-comp-course/project/phase6) | `mountainsolve_thread` | [MountainRangeThreaded](src/MountainRangeThreaded.hpp) |
Expand Down
86 changes: 0 additions & 86 deletions docs/MountainRange-sequence-diagram.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/MountainRange-sequence-diagram.md
83 changes: 83 additions & 0 deletions docs/MountainRangeBasic-sequence-diagram.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Mountain Range Basic — Sequence Diagram

> [!IMPORTANT]
> This diagram relies on [Mermaid diagrams](https://mermaid.js.org/) which display properly when rendered within GitHub.
>
> It may not work properly when rendered within other websites. [Click here to view the source](https://github.com/BYUHPC/sci-comp-course-example-cxx/blob/main/docs/MountainRangeBasic-sequence-diagram.md).

## Intro

This [sequence diagram](https://mermaid.js.org/syntax/sequenceDiagram.html#sequence-diagrams) written with Mermaid visually represents the calls and work being performed in the `MountainRange` example.

It is designed to help visualize the relationships between the various entities involved in running the program.

The code covered by this diagram exists in two separate example files:
* [MountainRangeBasic.hpp](../src/MountainRangeBasic.hpp) (base class)
* [initial.cpp](../src/initial.cpp) (driver code)

## Diagram

```mermaid
---
title: Mountain Range — Sequence Diagram
---

sequenceDiagram

participant main
participant MR as MountainRangeBasic
participant cout as std::cout

note left of main: Program starts
activate main

%% Initialize MountainRange
note over main,MR: Construct MountainRange
note right of main: Init constants and<br>fill vectors with zeros.
main->>+MR: constructor()
MR->>+MR: step(0)
note right of MR: Initialize g
MR-->>-MR: void
MR-->>-main: MountainRange
%% End construct MountainRange

%% Call Solve
note over main,MR: Begin Solving
main->>+MR: solve()
loop While dsteepness() > epsilon()

%% Evaluate steepness
MR->>+MR: dsteepness()
loop for cell in interior cells
MR->>MR: ds_cell(cell)
end
MR-->>-MR: total energy

%% Perform step
MR->>+MR: step()
%% Modify h cells
loop for cell in cells
MR->>MR: update_h_cell(cell)
end

%% Modify g cells
loop for cell in interior cells
MR->>MR: update_g_cell(cell)
end

%% Update other state variables
note right of MR: Update other state variables
MR-->>-MR: void

end
MR-->>-main: t
%% End solve

%% Print result
note over main,MR: Print Result
main->>cout: t << std::endl
%% end print

note left of main: Program exits
deactivate main
```
92 changes: 92 additions & 0 deletions src/MountainRangeBasic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once
#include <vector>
#include <cmath>
#include <limits>


// This header containes the Basic MountainRange class. It is a simplification of the MountainRange class.


// Basic MountainRange. Derived classes can override write, dsteepness, and step.
class MountainRangeBasic {
public:
using size_type = size_t;
using value_type = double;


protected:
// Parameters and members
static constexpr const value_type default_dt = 0.01;
const size_type ndims, cells;
value_type t;
std::vector<value_type> r, h, g;


public:
// Accessors
auto size() const { return cells; }
auto sim_time() const { return t; }
auto &uplift_rate() const { return r; }
auto &height() const { return h; }

// Build a MountainRange from an uplift rate and a current height
MountainRangeBasic(const auto &r, const auto &h): ndims{1ul}, cells{r.size()}, t{0.0}, r{r}, h{h} {
step(0);
}


protected:
// Helpers for step and dsteepness
constexpr void update_g_cell(auto i) {
auto L = (h[i-1] + h[i+1]) / 2 - h[i];
g[i] = r[i] - pow(h[i], 3) + L;
}

constexpr void update_h_cell(auto i, auto dt) {
h[i] += g[i] * dt;
}

constexpr value_type ds_cell(auto i) const {
return ((h[i-1] - h[i+1]) * (g[i-1] - g[i+1])) / 2 / (cells - 2);
}


public:
// Calculate the steepness derivative
virtual value_type dsteepness() {
value_type ds = 0;
for (size_t i=1; i<h.size()-1; i++) ds += ds_cell(i);
return ds;
}


// Step from t to t+dt in one step
virtual value_type step(value_type dt) {
// Update h
for (size_t i=0; i<h.size(); i++) update_h_cell(i, dt);

// Update g
for (size_t i=1; i<g.size()-1; i++) update_g_cell(i);

// Enforce boundary condition
g[0] = g[1];
g[g.size()-1] = g[g.size()-2];

// Increment time step
t += dt;
return t;
}


// Step until dsteepness() falls below 0, checkpointing along the way
value_type solve() {

// Solve loop
while (dsteepness() > std::numeric_limits<value_type>::epsilon()) {
step(default_dt);
}

// Return total simulation time
return t;
}
};
7 changes: 2 additions & 5 deletions src/initial.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
#include <vector>
#include <iostream>
#include "MountainRange.hpp"

#include "MountainRangeBasic.hpp"


// Run a basic mountain range simulation and print its simulation time



int main() {
// Simulation parameters
size_t len = 1000;
Expand All @@ -18,7 +15,7 @@ int main() {
std::vector<decltype(value)> r(len), h(len);
std::fill(r.begin()+plateau_start, r.begin()+plateau_end, value);
h[0] = 1;
auto m = MountainRange(r, h);
auto m = MountainRangeBasic(r, h);

// Solve and return
std::cout << m.solve() << std::endl;
Expand Down