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