xref: /honee/problems/sgs_dd_model.c (revision c38c977aa4558b391c15066825dc4f5ebc5269fc)
162b7942eSJames Wright // Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and other CEED contributors.
262b7942eSJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
362b7942eSJames Wright //
462b7942eSJames Wright // SPDX-License-Identifier: BSD-2-Clause
562b7942eSJames Wright //
662b7942eSJames Wright // This file is part of CEED:  http://github.com/ceed
762b7942eSJames Wright 
862b7942eSJames Wright #include "../qfunctions/sgs_dd_model.h"
962b7942eSJames Wright 
1062b7942eSJames Wright #include <petscdmplex.h>
1162b7942eSJames Wright 
1262b7942eSJames Wright #include "../navierstokes.h"
1362b7942eSJames Wright 
14*c38c977aSJames Wright typedef struct {
15*c38c977aSJames Wright   CeedElemRestriction  elem_restr_grid_aniso, elem_restr_sgs;
16*c38c977aSJames Wright   CeedVector           grid_aniso_ceed;
17*c38c977aSJames Wright } *SGS_DD_ModelSetupData;
18*c38c977aSJames Wright 
19*c38c977aSJames Wright PetscErrorCode SGS_DD_ModelSetupDataDestroy(SGS_DD_ModelSetupData sgs_dd_setup_data) {
20*c38c977aSJames Wright   PetscFunctionBeginUser;
21*c38c977aSJames Wright   CeedElemRestrictionDestroy(&sgs_dd_setup_data->elem_restr_grid_aniso);
22*c38c977aSJames Wright   CeedElemRestrictionDestroy(&sgs_dd_setup_data->elem_restr_sgs);
23*c38c977aSJames Wright   CeedVectorDestroy(&sgs_dd_setup_data->grid_aniso_ceed);
24*c38c977aSJames Wright 
25*c38c977aSJames Wright   PetscCall(PetscFree(sgs_dd_setup_data));
26*c38c977aSJames Wright   PetscFunctionReturn(0);
27*c38c977aSJames Wright }
28*c38c977aSJames Wright 
2962b7942eSJames Wright // @brief B = A^T, A is NxM, B is MxN
3062b7942eSJames Wright PetscErrorCode TransposeMatrix(const PetscScalar *A, PetscScalar *B, const PetscInt N, const PetscInt M) {
3162b7942eSJames Wright   PetscFunctionBeginUser;
3262b7942eSJames Wright   for (PetscInt i = 0; i < N; i++) {
3362b7942eSJames Wright     for (PetscInt j = 0; j < M; j++) {
3462b7942eSJames Wright       B[j * N + i] = A[i * M + j];
3562b7942eSJames Wright     }
3662b7942eSJames Wright   }
3762b7942eSJames Wright   PetscFunctionReturn(0);
3862b7942eSJames Wright }
3962b7942eSJames Wright 
4062b7942eSJames Wright // @brief Read neural network coefficients from file and put into context struct
4162b7942eSJames Wright PetscErrorCode SGS_DD_ModelContextFill(MPI_Comm comm, char data_dir[PETSC_MAX_PATH_LEN], SGS_DDModelContext *psgsdd_ctx) {
4262b7942eSJames Wright   SGS_DDModelContext sgsdd_ctx;
4362b7942eSJames Wright   PetscInt           num_inputs = (*psgsdd_ctx)->num_inputs, num_outputs = (*psgsdd_ctx)->num_outputs, num_neurons = (*psgsdd_ctx)->num_neurons;
4462b7942eSJames Wright   char               file_path[PETSC_MAX_PATH_LEN];
4562b7942eSJames Wright   PetscScalar       *temp;
4662b7942eSJames Wright 
4762b7942eSJames Wright   PetscFunctionBeginUser;
4862b7942eSJames Wright   {
4962b7942eSJames Wright     SGS_DDModelContext sgsdd_temp;
5062b7942eSJames Wright     PetscCall(PetscNew(&sgsdd_temp));
5162b7942eSJames Wright     *sgsdd_temp                     = **psgsdd_ctx;
5262b7942eSJames Wright     sgsdd_temp->offsets.bias1       = 0;
5362b7942eSJames Wright     sgsdd_temp->offsets.bias2       = sgsdd_temp->offsets.bias1 + num_neurons;
5462b7942eSJames Wright     sgsdd_temp->offsets.weight1     = sgsdd_temp->offsets.bias2 + num_neurons;
5562b7942eSJames Wright     sgsdd_temp->offsets.weight2     = sgsdd_temp->offsets.weight1 + num_neurons * num_inputs;
5662b7942eSJames Wright     sgsdd_temp->offsets.out_scaling = sgsdd_temp->offsets.weight2 + num_inputs * num_neurons;
5762b7942eSJames Wright     PetscInt total_num_scalars      = sgsdd_temp->offsets.out_scaling + 2 * num_outputs;
5862b7942eSJames Wright     sgsdd_temp->total_bytes         = sizeof(*sgsdd_ctx) + total_num_scalars * sizeof(sgsdd_ctx->data[0]);
5962b7942eSJames Wright     PetscCall(PetscMalloc(sgsdd_temp->total_bytes, &sgsdd_ctx));
6062b7942eSJames Wright     *sgsdd_ctx = *sgsdd_temp;
6162b7942eSJames Wright     PetscCall(PetscFree(sgsdd_temp));
6262b7942eSJames Wright   }
6362b7942eSJames Wright 
6462b7942eSJames Wright   PetscCall(PetscSNPrintf(file_path, sizeof file_path, "%s/%s", data_dir, "b1.dat"));
6562b7942eSJames Wright   PetscCall(PHASTADatFileReadToArrayReal(comm, file_path, &sgsdd_ctx->data[sgsdd_ctx->offsets.bias1]));
6662b7942eSJames Wright   PetscCall(PetscSNPrintf(file_path, sizeof file_path, "%s/%s", data_dir, "b2.dat"));
6762b7942eSJames Wright   PetscCall(PHASTADatFileReadToArrayReal(comm, file_path, &sgsdd_ctx->data[sgsdd_ctx->offsets.bias2]));
6862b7942eSJames Wright   PetscCall(PetscSNPrintf(file_path, sizeof file_path, "%s/%s", data_dir, "OutScaling.dat"));
6962b7942eSJames Wright   PetscCall(PHASTADatFileReadToArrayReal(comm, file_path, &sgsdd_ctx->data[sgsdd_ctx->offsets.out_scaling]));
7062b7942eSJames Wright 
7162b7942eSJames Wright   {
7262b7942eSJames Wright     PetscCall(PetscMalloc1(num_inputs * num_neurons, &temp));
7362b7942eSJames Wright     PetscCall(PetscSNPrintf(file_path, sizeof file_path, "%s/%s", data_dir, "w1.dat"));
7462b7942eSJames Wright     PetscCall(PHASTADatFileReadToArrayReal(comm, file_path, temp));
7562b7942eSJames Wright     PetscCall(TransposeMatrix(temp, &sgsdd_ctx->data[sgsdd_ctx->offsets.weight1], num_inputs, num_neurons));
7662b7942eSJames Wright     PetscCall(PetscFree(temp));
7762b7942eSJames Wright   }
7862b7942eSJames Wright   {
7962b7942eSJames Wright     PetscCall(PetscMalloc1(num_outputs * num_neurons, &temp));
8062b7942eSJames Wright     PetscCall(PetscSNPrintf(file_path, sizeof file_path, "%s/%s", data_dir, "w2.dat"));
8162b7942eSJames Wright     PetscCall(PHASTADatFileReadToArrayReal(comm, file_path, temp));
8262b7942eSJames Wright     PetscCall(TransposeMatrix(temp, &sgsdd_ctx->data[sgsdd_ctx->offsets.weight2], num_neurons, num_outputs));
8362b7942eSJames Wright     PetscCall(PetscFree(temp));
8462b7942eSJames Wright   }
8562b7942eSJames Wright 
8662b7942eSJames Wright   PetscCall(PetscFree(*psgsdd_ctx));
8762b7942eSJames Wright   *psgsdd_ctx = sgsdd_ctx;
8862b7942eSJames Wright   PetscFunctionReturn(0);
8962b7942eSJames Wright }
9062b7942eSJames Wright 
9162b7942eSJames Wright PetscErrorCode SGS_DD_ModelSetup(Ceed ceed, User user, CeedData ceed_data, ProblemData *problem) {
9262b7942eSJames Wright   PetscReal             alpha;
9362b7942eSJames Wright   SGS_DDModelContext    sgsdd_ctx;
9462b7942eSJames Wright   MPI_Comm              comm                           = user->comm;
9562b7942eSJames Wright   char                  sgs_dd_dir[PETSC_MAX_PATH_LEN] = "./dd_sgs_data";
96*c38c977aSJames Wright   SGS_DD_ModelSetupData sgs_dd_setup_data;
9762b7942eSJames Wright   PetscFunctionBeginUser;
9862b7942eSJames Wright 
999ab09d51SJames Wright   PetscCall(VelocityGradientProjectionSetup(ceed, user, ceed_data, problem));
1009ab09d51SJames Wright 
10162b7942eSJames Wright   PetscCall(PetscNew(&sgsdd_ctx));
10262b7942eSJames Wright 
10362b7942eSJames Wright   PetscOptionsBegin(comm, NULL, "SGS Data-Drive Model Options", NULL);
10462b7942eSJames Wright   PetscCall(PetscOptionsReal("-sgs_model_dd_leakyrelu_alpha", "Slope parameter for Leaky ReLU activation function", NULL, alpha, &alpha, NULL));
10562b7942eSJames Wright   PetscCall(PetscOptionsString("-sgs_model_dd_parameter_dir", "Path to directory with model parameters (weights, biases, etc.)", NULL, sgs_dd_dir,
10662b7942eSJames Wright                                sgs_dd_dir, sizeof(sgs_dd_dir), NULL));
10762b7942eSJames Wright   PetscOptionsEnd();
10862b7942eSJames Wright 
10962b7942eSJames Wright   sgsdd_ctx->num_layers  = 2;
11062b7942eSJames Wright   sgsdd_ctx->num_inputs  = 6;
11162b7942eSJames Wright   sgsdd_ctx->num_outputs = 6;
11262b7942eSJames Wright   sgsdd_ctx->num_neurons = 20;
11362b7942eSJames Wright   sgsdd_ctx->alpha       = alpha;
11462b7942eSJames Wright 
11562b7942eSJames Wright   // PetscCall(SGS_DD_ModelContextFill(comm, sgs_dd_dir, &sgsdd_ctx));
11662b7942eSJames Wright 
117*c38c977aSJames Wright   PetscCall(PetscNew(&sgs_dd_setup_data));
118*c38c977aSJames Wright 
119*c38c977aSJames Wright   // -- Compute and store anisotropy tensor
120*c38c977aSJames Wright   PetscCall(GridAnisotropyTensorProjectionSetupApply(ceed, user, ceed_data, &sgs_dd_setup_data->elem_restr_grid_aniso,
121*c38c977aSJames Wright                                                      &sgs_dd_setup_data->grid_aniso_ceed));
122*c38c977aSJames Wright 
123*c38c977aSJames Wright   PetscCall(SGS_DD_ModelSetupDataDestroy(sgs_dd_setup_data));
12462b7942eSJames Wright   PetscFunctionReturn(0);
12562b7942eSJames Wright }
126