-
Notifications
You must be signed in to change notification settings - Fork 11
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
Implementation of basic time integration #158
Merged
Merged
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
d888bde
add documentation
HenningScheufler 2140ab8
documentation update
HenningScheufler 8c97fb2
Apply suggestions from code review
HenningScheufler 03ef014
Apply suggestions from code review
greole 00daf21
build always a documentation
greole a71a79f
comment test url
greole ed7c326
keep one sentence per line
greole 72ed98a
move DSL documentation
greole 5b0cac0
move DSL documentation
greole d964046
wording change plus/minus ->addition,subtraction. Deduplicate
greole 00097bd
init implemnetation of the DSL
HenningScheufler a79e5a7
categorize terms into temporal, implicit and sources
HenningScheufler a2f18f8
added forward euler as integration method
HenningScheufler 29bf3f4
changes kokkos header
HenningScheufler 3a954c5
eqnTerm uses field
HenningScheufler 90ec6ee
initial commit
greole d2aa274
FIX: false specified executor
HenningScheufler 5f64d8c
WIP: forwardEuler
HenningScheufler 8ec3309
added dt to eqnsystem
HenningScheufler d2109e7
DSl use move semantics reduce complexity to linear
HenningScheufler fd165d0
Pull scaling field from from #136
greole b10bb2b
refactor scalingFields to coeff
greole 7e43c6b
Update include/NeoFOAM/DSL/coeff.hpp
greole 634568a
fix namespace and toField docstring
greole fc4c38b
move toField to free function
greole 929d37e
fix: getSpan tests segfault on GPU span access GPU memory from CPU
HenningScheufler e2af6cd
test coeff in parallelfor
HenningScheufler 7377af8
Merge pull request #151 from exasim-project/impl/scalingField
HenningScheufler 549daa6
wip add modifications to operators
greole 2a9c309
refactor constructors
greole 9f01abb
wip add tests
greole ba1a68f
rename input/add further operator tests
greole 627bf90
add getName()
greole 62f2fc5
fix format
greole f9e82e8
add getName function
greole 7111a82
remove evaluated
greole 135b918
remove field and nCells
greole 281137e
refactor operator=
greole 7516cc3
remove operator=
greole 37b8763
Merge pull request #152 from exasim-project/impl/eqnTerm
greole d376d27
renamed EqnSystem->Equation
greole 13905d1
mark explicitOperation as const
greole b5bc333
add overload for explicitOperation
greole 9c8aa79
remove volumeField for now
greole b182f06
Merge pull request #150 from exasim-project/impl/dsl_interface
greole e0098fc
update class names
greole 2c01069
Merge pull request #147 from exasim-project/doc/dsl
greole 852a433
wip refactor timeintegration
greole a3d2d4f
reorganize, change DSL->dsl, move timeIntegration to dsl
greole a9bf558
fix warnings, clean NeoFOAM:: in test
greole 50f6c7c
wip time integration
greole c5d5c6a
use and test dedicated ddt operator
greole 51df98e
add free solve function
greole 34fc503
improve error message for non matching executors
greole ecfeac7
add size() getter
greole f102094
make exec() method final
greole e5f5a95
add time setter/getter, docstrings, pass dictionaries
greole 38a97a2
improve simple time integration test
greole 41acd45
remove EquationType template argument
greole 83be03a
move solve out of equation
greole 08a2fa8
rename Equation -> Expression
greole a61ec61
reorganize structure
greole ee0f1c0
Apply suggestions from code review
greole 1e08f07
require field in OperatorMixin
greole 3993582
remove dt from equation, fix warnings
greole ce14d19
remove unused file, rename timeIntegrationFactory->timeIntegrationBase
greole 7a755e5
Merge branch 'stack/dsl' into impl/timeIntegration
greole adb378f
fixup
greole File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// SPDX-License-Identifier: MIT | ||
// SPDX-FileCopyrightText: 2023 NeoFOAM authors | ||
#pragma once | ||
|
||
namespace NeoFOAM::dsl | ||
{ | ||
|
||
/** | ||
* @class Coeff | ||
* @brief A class that represents a coefficient for the NeoFOAM dsl. | ||
* | ||
* This class stores a single scalar coefficient and optionally span of values. | ||
* It is used to delay the evaluation of a scalar multiplication with a field to | ||
* avoid the creation of a temporary field copy. | ||
* It provides an indexing operator `operator[]` that returns the evaluated value at the specified | ||
* index. | ||
*/ | ||
class Coeff | ||
{ | ||
|
||
public: | ||
|
||
Coeff() : coeff_(1.0), span_(), hasSpan_(false) {} | ||
|
||
Coeff(scalar value) : coeff_(value), span_(), hasSpan_(false) {} | ||
|
||
Coeff(scalar coeff, const Field<scalar>& field) | ||
: coeff_(coeff), span_(field.span()), hasSpan_(true) | ||
{} | ||
|
||
Coeff(const Field<scalar>& field) : coeff_(1.0), span_(field.span()), hasSpan_(true) {} | ||
|
||
KOKKOS_INLINE_FUNCTION | ||
scalar operator[](const size_t i) const { return (hasSpan_) ? span_[i] * coeff_ : coeff_; } | ||
|
||
bool hasSpan() { return hasSpan_; } | ||
|
||
std::span<const scalar> span() { return span_; } | ||
|
||
Coeff& operator*=(scalar rhs) | ||
{ | ||
coeff_ *= rhs; | ||
return *this; | ||
} | ||
|
||
Coeff& operator*=(const Coeff& rhs) | ||
{ | ||
if (hasSpan_ && rhs.hasSpan_) | ||
{ | ||
NF_ERROR_EXIT("Not implemented"); | ||
} | ||
|
||
if (!hasSpan_ && rhs.hasSpan_) | ||
{ | ||
// Take over the span | ||
span_ = rhs.span_; | ||
hasSpan_ = true; | ||
} | ||
|
||
return this->operator*=(rhs.coeff_); | ||
} | ||
|
||
|
||
private: | ||
|
||
scalar coeff_; | ||
|
||
std::span<const scalar> span_; | ||
|
||
bool hasSpan_; | ||
}; | ||
|
||
|
||
namespace detail | ||
|
||
{ | ||
/* @brief function to force evaluation to a field, the field will be resized to hold either a | ||
* single value or the full field | ||
* | ||
* @param field to store the result | ||
*/ | ||
void toField(Coeff& coeff, Field<scalar>& rhs) | ||
{ | ||
if (coeff.hasSpan()) | ||
{ | ||
rhs.resize(coeff.span().size()); | ||
fill(rhs, 1.0); | ||
auto rhsSpan = rhs.span(); | ||
// otherwise we are unable to capture values in the lambda | ||
parallelFor( | ||
rhs.exec(), rhs.range(), KOKKOS_LAMBDA(const size_t i) { rhsSpan[i] *= coeff[i]; } | ||
); | ||
} | ||
else | ||
{ | ||
rhs.resize(1); | ||
fill(rhs, coeff[0]); | ||
} | ||
} | ||
|
||
} | ||
|
||
inline Coeff operator*(const Coeff& lhs, const Coeff& rhs) | ||
{ | ||
Coeff result = lhs; | ||
result *= rhs; | ||
return result; | ||
} | ||
|
||
} // namespace NeoFOAM::dsl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: MIT | ||
// | ||
// SPDX-FileCopyrightText: 2023 NeoFOAM authors | ||
|
||
#pragma once | ||
|
||
#include "NeoFOAM/fields/field.hpp" | ||
#include "NeoFOAM/finiteVolume/cellCentred.hpp" | ||
#include "NeoFOAM/finiteVolume/cellCentred/fields/volumeField.hpp" | ||
|
||
namespace NeoFOAM::dsl::temporal | ||
{ | ||
|
||
|
||
// TODO add free factory function | ||
template<typename FieldType> | ||
class Ddt : public OperatorMixin<FieldType> | ||
{ | ||
|
||
public: | ||
|
||
Ddt(FieldType& field) : OperatorMixin<FieldType>(field.exec(), field, Operator::Type::Temporal) | ||
{} | ||
|
||
std::string getName() const { return "TimeOperator"; } | ||
|
||
void explicitOperation([[maybe_unused]] Field<scalar>& source, [[maybe_unused]] scalar scale) | ||
{ | ||
NF_ERROR_EXIT("Not implemented"); | ||
} | ||
|
||
void implicitOperation([[maybe_unused]] Field<scalar>& phi) | ||
{ | ||
NF_ERROR_EXIT("Not implemented"); | ||
} | ||
|
||
private: | ||
}; | ||
|
||
// see | ||
// https://github.com/exasim-project/NeoFOAM/blob/dsl/operatorIntergration/include/NeoFOAM/finiteVolume/cellCentred/operators/explicitOperators/expOp.hpp | ||
|
||
template<typename FieldType> | ||
Ddt<FieldType> ddt(FieldType& in) | ||
{ | ||
return Ddt(in); | ||
}; | ||
|
||
|
||
} // namespace NeoFOAM |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,170 @@ | ||||||
// SPDX-License-Identifier: MIT | ||||||
// SPDX-FileCopyrightText: 2023-2024 NeoFOAM authors | ||||||
#pragma once | ||||||
|
||||||
#include <iostream> | ||||||
#include <memory> | ||||||
#include <vector> | ||||||
#include <utility> | ||||||
|
||||||
#include "NeoFOAM/core/primitives/scalar.hpp" | ||||||
#include "NeoFOAM/fields/field.hpp" | ||||||
#include "NeoFOAM/dsl/operator.hpp" | ||||||
#include "NeoFOAM/core/error.hpp" | ||||||
|
||||||
#include "NeoFOAM/finiteVolume/cellCentred/fields/volumeField.hpp" | ||||||
|
||||||
namespace NeoFOAM::dsl | ||||||
{ | ||||||
|
||||||
|
||||||
class Expression | ||||||
{ | ||||||
public: | ||||||
|
||||||
Expression(const Executor& exec) | ||||||
: exec_(exec), temporalOperators_(), implicitOperators_(), explicitOperators_() | ||||||
{} | ||||||
|
||||||
/* @brief perform all explicit operation and accumulate the result */ | ||||||
Field<scalar> explicitOperation(size_t nCells) const | ||||||
{ | ||||||
Field<scalar> source(exec_, nCells, 0.0); | ||||||
return explicitOperation(source); | ||||||
} | ||||||
|
||||||
/* @brief perform all explicit operation and accumulate the result */ | ||||||
Field<scalar> explicitOperation(Field<scalar>& source) const | ||||||
{ | ||||||
for (auto& Operator : explicitOperators_) | ||||||
{ | ||||||
Operator.explicitOperation(source); | ||||||
} | ||||||
return source; | ||||||
} | ||||||
|
||||||
void addOperator(const Operator& Operator) | ||||||
{ | ||||||
switch (Operator.getType()) | ||||||
{ | ||||||
case Operator::Type::Temporal: | ||||||
temporalOperators_.push_back(Operator); | ||||||
break; | ||||||
case Operator::Type::Implicit: | ||||||
implicitOperators_.push_back(Operator); | ||||||
break; | ||||||
case Operator::Type::Explicit: | ||||||
explicitOperators_.push_back(Operator); | ||||||
break; | ||||||
} | ||||||
} | ||||||
|
||||||
void addExpression(const Expression& equation) | ||||||
{ | ||||||
for (auto& Operator : equation.temporalOperators_) | ||||||
{ | ||||||
temporalOperators_.push_back(Operator); | ||||||
} | ||||||
for (auto& Operator : equation.implicitOperators_) | ||||||
{ | ||||||
implicitOperators_.push_back(Operator); | ||||||
} | ||||||
for (auto& Operator : equation.explicitOperators_) | ||||||
{ | ||||||
explicitOperators_.push_back(Operator); | ||||||
} | ||||||
} | ||||||
|
||||||
|
||||||
/* @brief getter for the total number of terms in the equation */ | ||||||
size_t size() const | ||||||
{ | ||||||
return temporalOperators_.size() + implicitOperators_.size() + explicitOperators_.size(); | ||||||
} | ||||||
|
||||||
// getters | ||||||
const std::vector<Operator>& temporalOperators() const { return temporalOperators_; } | ||||||
|
||||||
const std::vector<Operator>& implicitOperators() const { return implicitOperators_; } | ||||||
|
||||||
const std::vector<Operator>& explicitOperators() const { return explicitOperators_; } | ||||||
|
||||||
std::vector<Operator>& temporalOperators() { return temporalOperators_; } | ||||||
|
||||||
std::vector<Operator>& implicitOperators() { return implicitOperators_; } | ||||||
|
||||||
std::vector<Operator>& explicitOperators() { return explicitOperators_; } | ||||||
|
||||||
const Executor& exec() const { return exec_; } | ||||||
|
||||||
private: | ||||||
|
||||||
const Executor exec_; | ||||||
|
||||||
std::vector<Operator> temporalOperators_; | ||||||
|
||||||
std::vector<Operator> implicitOperators_; | ||||||
|
||||||
std::vector<Operator> explicitOperators_; | ||||||
}; | ||||||
|
||||||
Expression operator+(Expression lhs, const Expression& rhs) | ||||||
{ | ||||||
lhs.addExpression(rhs); | ||||||
return lhs; | ||||||
} | ||||||
|
||||||
Expression operator+(Expression lhs, const Operator& rhs) | ||||||
greole marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
lhs.addOperator(rhs); | ||||||
return lhs; | ||||||
} | ||||||
|
||||||
Expression operator+(const Operator& lhs, const Operator& rhs) | ||||||
greole marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
Expression expr(lhs.exec()); | ||||||
expr.addOperator(lhs); | ||||||
expr.addOperator(rhs); | ||||||
return expr; | ||||||
} | ||||||
|
||||||
Expression operator*(scalar scale, const Expression& es) | ||||||
greole marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
Expression expr(es.exec()); | ||||||
for (const auto& Operator : es.temporalOperators()) | ||||||
{ | ||||||
expr.addOperator(scale * Operator); | ||||||
} | ||||||
for (const auto& Operator : es.implicitOperators()) | ||||||
{ | ||||||
expr.addOperator(scale * Operator); | ||||||
} | ||||||
for (const auto& Operator : es.explicitOperators()) | ||||||
{ | ||||||
expr.addOperator(scale * Operator); | ||||||
} | ||||||
return expr; | ||||||
} | ||||||
|
||||||
Expression operator-(Expression lhs, const Expression& rhs) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
lhs.addExpression(-1.0 * rhs); | ||||||
return lhs; | ||||||
} | ||||||
|
||||||
Expression operator-(Expression lhs, const Operator& rhs) | ||||||
greole marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
{ | ||||||
lhs.addOperator(-1.0 * rhs); | ||||||
return lhs; | ||||||
} | ||||||
|
||||||
Expression operator-(const Operator& lhs, const Operator& rhs) | ||||||
{ | ||||||
Expression expr(lhs.exec()); | ||||||
expr.addOperator(lhs); | ||||||
expr.addOperator(Coeff(-1) * rhs); | ||||||
return expr; | ||||||
} | ||||||
|
||||||
|
||||||
} // namespace NeoFOAM::dsl |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if we have an approach to inlining - I know ultimately it's the compiler that decides, so it can be pretty redundant. I will add suggestions for all the below functions (and other places). Take it or leave it ;) - Perhaps we should add a guideline for this to some kind of conversions doc (not sure if we have one)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets discuss it on thursday, but my current opinion is to leave it like it is (without the
inline
) for now. To my knowledge the compiler can decide to inline withoutinline
keyword and to not inline even withinline
keyword.