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

Implementation of basic time integration #158

Merged
merged 68 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d888bde
add documentation
HenningScheufler Sep 4, 2024
2140ab8
documentation update
HenningScheufler Sep 4, 2024
8c97fb2
Apply suggestions from code review
HenningScheufler Sep 5, 2024
03ef014
Apply suggestions from code review
greole Sep 29, 2024
00daf21
build always a documentation
greole Sep 30, 2024
a71a79f
comment test url
greole Sep 30, 2024
ed7c326
keep one sentence per line
greole Sep 30, 2024
72ed98a
move DSL documentation
greole Sep 30, 2024
5b0cac0
move DSL documentation
greole Sep 30, 2024
d964046
wording change plus/minus ->addition,subtraction. Deduplicate
greole Sep 30, 2024
00097bd
init implemnetation of the DSL
HenningScheufler Jul 24, 2024
a79e5a7
categorize terms into temporal, implicit and sources
HenningScheufler Jul 25, 2024
a2f18f8
added forward euler as integration method
HenningScheufler Jul 25, 2024
29bf3f4
changes kokkos header
HenningScheufler Jul 25, 2024
3a954c5
eqnTerm uses field
HenningScheufler Jul 25, 2024
90ec6ee
initial commit
greole Jul 11, 2024
d2aa274
FIX: false specified executor
HenningScheufler Jul 26, 2024
5f64d8c
WIP: forwardEuler
HenningScheufler Jul 26, 2024
8ec3309
added dt to eqnsystem
HenningScheufler Jul 26, 2024
d2109e7
DSl use move semantics reduce complexity to linear
HenningScheufler Aug 10, 2024
fd165d0
Pull scaling field from from #136
greole Sep 30, 2024
b10bb2b
refactor scalingFields to coeff
greole Sep 30, 2024
7e43c6b
Update include/NeoFOAM/DSL/coeff.hpp
greole Oct 4, 2024
634568a
fix namespace and toField docstring
greole Oct 4, 2024
fc4c38b
move toField to free function
greole Oct 4, 2024
929d37e
fix: getSpan tests segfault on GPU span access GPU memory from CPU
HenningScheufler Oct 6, 2024
e2af6cd
test coeff in parallelfor
HenningScheufler Oct 6, 2024
7377af8
Merge pull request #151 from exasim-project/impl/scalingField
HenningScheufler Oct 6, 2024
549daa6
wip add modifications to operators
greole Oct 4, 2024
2a9c309
refactor constructors
greole Oct 4, 2024
9f01abb
wip add tests
greole Oct 5, 2024
ba1a68f
rename input/add further operator tests
greole Oct 7, 2024
627bf90
add getName()
greole Oct 7, 2024
62f2fc5
fix format
greole Oct 7, 2024
f9e82e8
add getName function
greole Oct 7, 2024
7111a82
remove evaluated
greole Oct 7, 2024
135b918
remove field and nCells
greole Oct 7, 2024
281137e
refactor operator=
greole Oct 7, 2024
7516cc3
remove operator=
greole Oct 7, 2024
37b8763
Merge pull request #152 from exasim-project/impl/eqnTerm
greole Oct 8, 2024
d376d27
renamed EqnSystem->Equation
greole Oct 7, 2024
13905d1
mark explicitOperation as const
greole Oct 7, 2024
b5bc333
add overload for explicitOperation
greole Oct 7, 2024
9c8aa79
remove volumeField for now
greole Oct 7, 2024
b182f06
Merge pull request #150 from exasim-project/impl/dsl_interface
greole Oct 8, 2024
e0098fc
update class names
greole Oct 10, 2024
2c01069
Merge pull request #147 from exasim-project/doc/dsl
greole Oct 10, 2024
852a433
wip refactor timeintegration
greole Oct 8, 2024
a3d2d4f
reorganize, change DSL->dsl, move timeIntegration to dsl
greole Oct 11, 2024
a9bf558
fix warnings, clean NeoFOAM:: in test
greole Oct 11, 2024
50f6c7c
wip time integration
greole Oct 11, 2024
c5d5c6a
use and test dedicated ddt operator
greole Oct 12, 2024
51df98e
add free solve function
greole Oct 13, 2024
34fc503
improve error message for non matching executors
greole Oct 14, 2024
ecfeac7
add size() getter
greole Oct 14, 2024
f102094
make exec() method final
greole Oct 14, 2024
e5f5a95
add time setter/getter, docstrings, pass dictionaries
greole Oct 14, 2024
38a97a2
improve simple time integration test
greole Oct 14, 2024
41acd45
remove EquationType template argument
greole Oct 16, 2024
83be03a
move solve out of equation
greole Oct 16, 2024
08a2fa8
rename Equation -> Expression
greole Oct 18, 2024
a61ec61
reorganize structure
greole Oct 18, 2024
ee0f1c0
Apply suggestions from code review
greole Oct 21, 2024
1e08f07
require field in OperatorMixin
greole Oct 25, 2024
3993582
remove dt from equation, fix warnings
greole Oct 25, 2024
ce14d19
remove unused file, rename timeIntegrationFactory->timeIntegrationBase
greole Oct 25, 2024
7a755e5
Merge branch 'stack/dsl' into impl/timeIntegration
greole Oct 25, 2024
adb378f
fixup
greole Oct 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions include/NeoFOAM/dsl/coeff.hpp
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
50 changes: 50 additions & 0 deletions include/NeoFOAM/dsl/ddt.hpp
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
170 changes: 170 additions & 0 deletions include/NeoFOAM/dsl/expression.hpp
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Expression operator+(Expression lhs, const Expression& rhs)
inline Expression operator+(Expression lhs, const Expression& rhs)

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)?

Copy link
Contributor Author

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 without inline keyword and to not inline even with inline keyword.

{
lhs.addExpression(rhs);
return lhs;
}

Expression operator+(Expression lhs, const Operator& rhs)
{
lhs.addOperator(rhs);
return lhs;
}

Expression operator+(const Operator& lhs, const Operator& rhs)
{
Expression expr(lhs.exec());
expr.addOperator(lhs);
expr.addOperator(rhs);
return expr;
}

Expression operator*(scalar scale, const Expression& es)
{
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Expression operator-(Expression lhs, const Expression& rhs)
inline Expression operator-(Expression lhs, const Expression& rhs)

{
lhs.addExpression(-1.0 * rhs);
return lhs;
}

Expression operator-(Expression lhs, const Operator& rhs)
{
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
Loading
Loading