Skip to content

Commit

Permalink
Merge pull request #12448 from KratosMultiphysics/core/expression/fea…
Browse files Browse the repository at this point in the history
…ture/add_log_expression

[Exp] Add Log Expression
  • Loading branch information
sunethwarna authored Jun 13, 2024
2 parents 19ad2ca + 6bd5de4 commit a25b485
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 83 deletions.
69 changes: 69 additions & 0 deletions docs/pages/Kratos/Expressions/Utilities/Log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: Log
keywords:
tags: [log, expression]
sidebar: kratos_expressions
summary:
---

## Introduction

This computes the component-wise natural logarithm of the given expression. Assume the input expression is given by $$\underline{\mathbf{u}} = \left\lbrace u_{ij}, \forall (i,j)\in\left[0, M\right)\times\left[0, N\right)\right\rbrace$$ where the $$i^{th}$$ entity's $$j^{th}$$ component is represented by $$u_{ij}$$ with $$i\in \left[0, M\right)$$ for each entity and $$j\in \left[0, N\right)$$ for each component in each entity. The Following equation illustrates the formulation of the resulting expression.

> ##### WARNING
>
> This method returns nan for any component which is $$u_{ij} < 0.0$$ and inf for $$u_{ij} = 0.0$$.
<p align="center">$$ Log\left(\underline{\mathbf{u}}\right) = \left\lbrace log\left(u_{ij}\right), \forall (i,j)\in\left[0, M\right)\times\left[0, N\right)\right\rbrace$$</p>

## Use cases

### Using to compute absolute values
```python
import KratosMultiphysics as Kratos
model = Kratos.Model()
model_part = model.CreateModelPart("test")

node_1 = model_part.CreateNewNode(1, 0, 0, 0)
node_2 = model_part.CreateNewNode(2, 1, 0, 0)
node_3 = model_part.CreateNewNode(3, 1, 1, 0)

# setting VELOCITY of each node
node_1.SetValue(Kratos.VELOCITY, Kratos.Array3([1,2,3]))
node_2.SetValue(Kratos.VELOCITY, Kratos.Array3([4,5,6]))
node_3.SetValue(Kratos.VELOCITY, Kratos.Array3([7,8,9]))

# create the nodal expression
nodal_expression = Kratos.Expression.NodalExpression(model_part)

# read the VELOCITY from non-historical nodal container
Kratos.Expression.VariableExpressionIO.Read(nodal_expression, Kratos.VELOCITY, False)

log_nodal_expression = Kratos.Expression.Utils.Log(nodal_expression)

# now write the absolute value for checking to the ACCELERATION
Kratos.Expression.VariableExpressionIO.Write(log_nodal_expression, Kratos.ACCELERATION, False)

# now printing
for node in model_part.Nodes:
velocity = node.GetValue(Kratos.VELOCITY)
acceleration = node.GetValue(Kratos.ACCELERATION)

print(f"node_id: {node.Id}, velocity=[{velocity[0]}, {velocity[1]}, {velocity[2]}], acceleration = [{acceleration[0]}, {acceleration[1]}, {acceleration[2]}]")
```

Expected output:
```console
| / |
' / __| _` | __| _ \ __|
. \ | ( | | ( |\__ \
_|\_\_| \__,_|\__|\___/ ____/
Multi-Physics 9.5."0"-core/expression/feature/add_log_expression-c757d39762-Release-x86_64
Compiled for GNU/Linux and Python3.12 with GCC-14.1
Compiled with threading and MPI support.
Maximum number of threads: 36.
Running without MPI.
node_id: 1, velocity=[1.0, 2.0, 3.0], acceleration = [0.0, 0.6931471805599453, 1.0986122886681098]
node_id: 2, velocity=[4.0, 5.0, 6.0], acceleration = [1.3862943611198906, 1.6094379124341003, 1.791759469228055]
node_id: 3, velocity=[7.0, 8.0, 9.0], acceleration = [1.9459101490553132, 2.0794415416798357, 2.1972245773362196]
```
13 changes: 11 additions & 2 deletions kratos/expression/expression_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "expression/binary_expression.h"
#include "expression/literal_expression.h"
#include "expression/literal_flat_expression.h"
#include "expression/unary_abs_expression.h"
#include "expression/unary_expression.h"
#include "expression/unary_slice_expression.h"
#include "expression/unary_statistics_expression.h"
#include "utilities/parallel_utilities.h"
Expand Down Expand Up @@ -90,7 +90,16 @@ Expression::ConstPointer ExpressionUtils::Abs(const Expression::ConstPointer& rp
{
KRATOS_TRY

return UnaryAbsExpression::Create(rpExpression);
return UnaryExpression<UnaryOperations::Absolute>::Create(rpExpression);

KRATOS_CATCH("");
}

Expression::ConstPointer ExpressionUtils::Log(const Expression::ConstPointer& rpExpression)
{
KRATOS_TRY

return UnaryExpression<UnaryOperations::Logarithm>::Create(rpExpression);

KRATOS_CATCH("");
}
Expand Down
51 changes: 35 additions & 16 deletions kratos/expression/expression_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression which represents the component wise absolute value of the given expression.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , then the returned expression \f$\left|\underline{\mathbb{u}}\right|\f$
*
* \f[
Expand All @@ -226,10 +226,28 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
*/
static Expression::ConstPointer Abs(const Expression::ConstPointer& rpExpression);

/**
* @brief Returns an expression which represents the component wise logarithmic value of the given expression.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , then the returned expression \f$\left|\underline{\mathbb{u}}\right|\f$
*
* \f[
* Log\left(\underline{\mathbb{u}}\right) = log\left(u_{ij}\right)
* \f]
*
* @warning Returns nan if the given $\f$u_{ij}\f < 0.0$
* @warning Returns inf if the given $\f$u_{ij}\f = 0.0$
*
* @return Expression::ConstPointer Expression which computes component wise logarithmic value.
*/
static Expression::ConstPointer Log(const Expression::ConstPointer& rpExpression);


/**
* @brief Returns an expression which raises each component to the given power.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , where P is specified by @a Power.
*
* \f[
Expand All @@ -245,8 +263,8 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression which raises each component to the given power from another expression.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* and the @a rpPowerpExpression is \f$\underline{\mathbb{P}}\f$, where \f$p_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* and the @a rpPowerpExpression is \f$\underline{\mathbb{P}}\f$, where \f$p_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , then the returned expression can be illustrated as below.
*
* \f[
Expand All @@ -270,7 +288,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression which scales each component to the specified value
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , where Scale is specified by @a Scale.
*
* \f[
Expand All @@ -286,8 +304,8 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression which scales each component by a value from another expression.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* and the @a rpScaleExpression is \f$\underline{\mathbb{s}}\f$, where \f$s_{ij}\f$ representss \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* and the @a rpScaleExpression is \f$\underline{\mathbb{s}}\f$, where \f$s_{ij}\f$ represents \f$j^{th}\f$ component of the flattened entity data for \f$i^{th}\f$ entity
* , then the returned expression can be illustrated as below.
*
* \f[
Expand All @@ -311,7 +329,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression having min value from all the components for each entity.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* , Following illustrates the returned expression which is always a scalar expression having \f$m_i\f$ representing the \f$i^{th}\f$ entity data.
*
* \f[
Expand All @@ -330,7 +348,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression having max value from all the components for each entity.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* , Following illustrates the returned expression which is always a scalar expression having \f$m_i\f$ representing the \f$i^{th}\f$ entity data.
*
* \f[
Expand All @@ -349,7 +367,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns an expression having sum of component values for each entity.
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity
* , Following illustrates the returned expression which is always a scalar expression having \f$m_i\f$ representing the \f$i^{th}\f$ entity data.
*
* \f[
Expand All @@ -372,7 +390,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns the sum of the expression assuming it is a flat vector [Shape is not considered].
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* , Following illustrates the returned value where the entity data is flattened.
*
* \f[
Expand All @@ -392,7 +410,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns the infinity norm of the expression assuming it is a flat vector [Shape is not considered].
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* , Following illustrates the returned value where the entity data is flattened.
*
* \f[
Expand All @@ -412,7 +430,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns the L2 norm of the expression assuming it is a flat vector [Shape is not considered].
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* , Following illustrates the returned value where the entity data is flattened.
*
* \f[
Expand All @@ -432,7 +450,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns the P norm of the expression assuming it is a flat vector [Shape is not considered].
*
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* @details If the input @a rpExpression is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* , Following illustrates the returned value where the entity data is flattened.
*
* \f[
Expand All @@ -454,8 +472,8 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils
/**
* @brief Returns the inner product between two expressions.
*
* @details If the input @a rpExpression1 is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* and the input @a rpExpression2 is \f$\underline{\mathbb{v}}\f$, where \f$v_{ij}\f$ representss \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities),
* @details If the input @a rpExpression1 is \f$\underline{\mathbb{u}}\f$, where \f$u_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities)
* and the input @a rpExpression2 is \f$\underline{\mathbb{v}}\f$, where \f$v_{ij}\f$ represents \f$j^{th}\f$ component of the flattened (having \f$N\f$ total components) entity data for \f$i^{th}\f$ entity (having \f$M\f$ entities),
* Following illustrates the returned value where the entity data is flattened. This does not consider shapes of the expressions. They should have same size of flattened vectors.
*
* \f[
Expand Down Expand Up @@ -553,6 +571,7 @@ class KRATOS_API(KRATOS_CORE) ExpressionUtils

KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(Collapse)
KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(Abs)
KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(Log)
KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(EntityMin)
KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(EntityMax)
KRATOS_EXPRESSION_UTILS_CEXP_METHOD_1(EntitySum)
Expand Down
60 changes: 0 additions & 60 deletions kratos/expression/unary_abs_expression.cpp

This file was deleted.

79 changes: 79 additions & 0 deletions kratos/expression/unary_expression.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// | / |
// ' / __| _` | __| _ \ __|
// . \ | ( | | ( |\__ `
// _|\_\_| \__,_|\__|\___/ ____/
// Multi-Physics
//
// License: BSD License
// Kratos default license: kratos/license.txt
//
// Main authors: Suneth Warnakulasuriya
//

// System includes
#include <sstream>
#include <type_traits>

// Project includes

// Include base h
#include "unary_expression.h"

namespace Kratos {

template <class TOperationType>
UnaryExpression<TOperationType>::UnaryExpression(Expression::ConstPointer pExpression)
: Expression(pExpression->NumberOfEntities()),
mpSourceExpression(pExpression)
{
}

template <class TOperationType>
Expression::Pointer UnaryExpression<TOperationType>::Create(Expression::ConstPointer pExpression)
{
return Kratos::make_intrusive<UnaryExpression<TOperationType>>(std::move(pExpression));
}

template <class TOperationType>
double UnaryExpression<TOperationType>::Evaluate(
const IndexType EntityIndex,
const IndexType EntityDataBeginIndex,
const IndexType ComponentIndex) const
{
return TOperationType::Evaluate(mpSourceExpression->Evaluate(EntityIndex, EntityDataBeginIndex, ComponentIndex));
}

template <class TOperationType>
const std::vector<std::size_t> UnaryExpression<TOperationType>::GetItemShape() const
{
return mpSourceExpression->GetItemShape();
}

template <class TOperationType>
std::size_t UnaryExpression<TOperationType>::GetMaxDepth() const
{
return mpSourceExpression->GetMaxDepth() + 1;
}

template <class TOperationType>
std::string UnaryExpression<TOperationType>::Info() const
{
std::stringstream msg;

if constexpr(std::is_same_v<TOperationType, UnaryOperations::Absolute>) {
msg << "Abs";
} else if constexpr(std::is_same_v<TOperationType, UnaryOperations::Logarithm>) {
msg << "Log";
} else {
static_assert(!std::is_same_v<TOperationType, TOperationType>, "Unsupported unary operation type.");
}

msg << "(" << mpSourceExpression << ")";
return msg.str();
}

// template instantiations
template class UnaryExpression<UnaryOperations::Absolute>;
template class UnaryExpression<UnaryOperations::Logarithm>;

} // namespace Kratos
Loading

0 comments on commit a25b485

Please sign in to comment.