⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 h5fields.cpp

📁 来自mit的fdtd开放性源代码meep
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2005-2008 Massachusetts Institute of Technology%%  This program is free software; you can redistribute it and/or modify%  it under the terms of the GNU General Public License as published by%  the Free Software Foundation; either version 2, or (at your option)%  any later version.%%  This program is distributed in the hope that it will be useful,%  but WITHOUT ANY WARRANTY; without even the implied warranty of%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the%  GNU General Public License for more details.%%  You should have received a copy of the GNU General Public License%  along with this program; if not, write to the Free Software Foundation,%  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* HDF5 output of fields and arbitrary functions thereof.  Works   very similarly to integrate.cpp (using fields::loop_in_chunks). */#include <stdio.h>#include <string.h>#include <math.h>#include "meep_internals.hpp"namespace meep {/***************************************************************************/typedef struct {  // information related to the HDF5 dataset (its size, etcetera)  h5file *file;  ivec min_corner, max_corner;  int num_chunks;  double *buf;  int bufsz;  int rank;  direction ds[3];  int reim; // whether to output the real or imaginary part  // the function to output and related info (offsets for averaging, etc.)  int num_fields;  const component *components;  component *cS;  complex<double> *ph;  complex<double> *fields;  int *offsets;  int ninveps;  component inveps_cs[3];  direction inveps_ds[3];  int ninvmu;  component invmu_cs[3];  direction invmu_ds[3];  complex<long double> sum;  field_function fun;  void *fun_data_;} h5_output_data;#define UNUSED(x) (void) x // silence compiler warningsstatic void h5_findsize_chunkloop(fields_chunk *fc, int ichnk, component cgrid,				  ivec is, ivec ie,				  vec s0, vec s1, vec e0, vec e1,				  double dV0, double dV1,				  ivec shift, complex<double> shift_phase,				  const symmetry &S, int sn,				  void *data_){  UNUSED(ichnk);UNUSED(cgrid);UNUSED(s0);UNUSED(s1);UNUSED(e0);UNUSED(e1);  UNUSED(dV0);UNUSED(dV1);UNUSED(shift_phase);  h5_output_data *data = (h5_output_data *) data_;  ivec isS = S.transform(is, sn) + shift;  ivec ieS = S.transform(ie, sn) + shift;  data->min_corner = min(data->min_corner, min(isS, ieS));  data->max_corner = max(data->max_corner, max(isS, ieS));  data->num_chunks++;  int bufsz = 1;  LOOP_OVER_DIRECTIONS(fc->v.dim, d)    bufsz *= (ie.in_direction(d) - is.in_direction(d)) / 2 + 1;  data->bufsz = max(data->bufsz, bufsz);}static void h5_output_chunkloop(fields_chunk *fc, int ichnk, component cgrid,				ivec is, ivec ie,				vec s0, vec s1, vec e0, vec e1,				double dV0, double dV1,				ivec shift, complex<double> shift_phase,				const symmetry &S, int sn,				void *data_){  UNUSED(ichnk);UNUSED(cgrid);UNUSED(s0);UNUSED(s1);UNUSED(e0);UNUSED(e1);  UNUSED(dV0);UNUSED(dV1);  h5_output_data *data = (h5_output_data *) data_;  //-----------------------------------------------------------------------//  // Find output chunk dimensions and strides, etc.  int start[3]={0,0,0}, count[3]={1,1,1};  int offset[3]={0,0,0}, stride[3]={1,1,1};  ivec isS = S.transform(is, sn) + shift;  ivec ieS = S.transform(ie, sn) + shift;    // figure out what yucky_directions (in LOOP_OVER_IVECS)  // correspond to what directions in the transformed vectors (in output).  ivec permute(zero_ivec(fc->v.dim));  for (int i = 0; i < 3; ++i)     permute.set_direction(fc->v.yucky_direction(i), i);  permute = S.transform_unshifted(permute, sn);  LOOP_OVER_DIRECTIONS(permute.dim, d)    permute.set_direction(d, abs(permute.in_direction(d)));    // compute the size of the chunk to output, and its strides etc.  for (int i = 0; i < data->rank; ++i) {    direction d = data->ds[i];    int isd = isS.in_direction(d), ied = ieS.in_direction(d);    start[i] = (min(isd, ied) - data->min_corner.in_direction(d)) / 2;    count[i] = abs(ied - isd) / 2 + 1;    if (ied < isd) offset[permute.in_direction(d)] = count[i] - 1;  }  for (int i = 0; i < data->rank; ++i) {    direction d = data->ds[i];    int j = permute.in_direction(d);    for (int k = i + 1; k < data->rank; ++k) stride[j] *= count[k];    offset[j] *= stride[j];    if (offset[j]) stride[j] *= -1;  }    //-----------------------------------------------------------------------//  // Compute the function to output, exactly as in fields::integrate,  // except that here we store its values in a buffer instead of integrating.  int *off = data->offsets;  component *cS = data->cS;  complex<double> *fields = data->fields, *ph = data->ph;  complex<long double> sum = 0.0;  const component *iecs = data->inveps_cs;  const direction *ieds = data->inveps_ds;  int ieos[6];  const component *imcs = data->invmu_cs;  const direction *imds = data->invmu_ds;  int imos[6];  for (int i = 0; i < data->num_fields; ++i) {    cS[i] = S.transform(data->components[i], -sn);    if (cS[i] == Dielectric || cS[i] == Permeability)      ph[i] = 1.0;    else {      fc->v.yee2diel_offsets(cS[i], off[2*i], off[2*i+1]);      ph[i] = shift_phase * S.phase_shift(cS[i], sn);    }  }  for (int k = 0; k < data->ninveps; ++k)    fc->v.yee2diel_offsets(iecs[k], ieos[2*k], ieos[2*k+1]);  for (int k = 0; k < data->ninvmu; ++k)    fc->v.yee2diel_offsets(imcs[k], imos[2*k], imos[2*k+1]);  vec rshift(shift * (0.5*fc->v.inva));  LOOP_OVER_IVECS(fc->v, is, ie, idx) {    IVEC_LOOP_LOC(fc->v, loc);    loc = S.transform(loc, sn) + rshift;    for (int i = 0; i < data->num_fields; ++i) {      if (cS[i] == Dielectric) {	double tr = 0.0;	for (int k = 0; k < data->ninveps; ++k)	  tr += (fc->s->inveps[iecs[k]][ieds[k]][idx]		 + fc->s->inveps[iecs[k]][ieds[k]][idx+ieos[2*k]]		 + fc->s->inveps[iecs[k]][ieds[k]][idx+ieos[1+2*k]]		 + fc->s->inveps[iecs[k]][ieds[k]][idx+ieos[2*k]+ieos[1+2*k]]);	fields[i] = (4 * data->ninveps) / tr;      }      else if (cS[i] == Permeability) {	double tr = 0.0;	for (int k = 0; k < data->ninvmu; ++k) {	  const double *im = fc->s->invmu[imcs[k]][imds[k]];	  if (im) tr += (im[idx] + im[idx+imos[2*k]] + im[idx+imos[1+2*k]]			 + im[idx+imos[2*k]+imos[1+2*k]]);	  else tr += 4; // default invmu == 1	}	fields[i] = (4 * data->ninvmu) / tr;      }      else {	double f[2];	for (int k = 0; k < 2; ++k)	  if (fc->f[cS[i]][k])	    f[k] = 0.25 * (fc->f[cS[i]][k][idx]			   + fc->f[cS[i]][k][idx+off[2*i]]			   + fc->f[cS[i]][k][idx+off[2*i+1]]			   + fc->f[cS[i]][k][idx+off[2*i]+off[2*i+1]]);	  else	    f[k] = 0;	fields[i] = complex<double>(f[0], f[1]) * ph[i];      }    }    complex<double> fun = data->fun(fields, loc, data->fun_data_);    int idx2 = ((((offset[0] + offset[1] + offset[2])		  + loop_i1 * stride[0]) 		 + loop_i2 * stride[1]) + loop_i3 * stride[2]);    data->buf[idx2] = data->reim ? imag(fun) : real(fun);  }  //-----------------------------------------------------------------------//  data->file->write_chunk(data->rank, start, count, data->buf);}void fields::output_hdf5(h5file *file, const char *dataname,			 int num_fields, const component *components,			 field_function fun, void *fun_data_, int reim,			 const geometric_volume &where,			 bool append_data,                         bool single_precision) {  am_now_working_on(FieldOutput);  h5_output_data data;  data.file = file;  data.min_corner = v.round_vec(where.get_max_corner()) + one_ivec(v.dim);  data.max_corner = v.round_vec(where.get_min_corner()) - one_ivec(v.dim);  data.num_chunks = 0;  data.bufsz = 0;  data.reim = reim;  loop_in_chunks(h5_findsize_chunkloop, (void *) &data, 	    where, Dielectric, true, true);  file->prevent_deadlock(); // can't hold a lock since *_to_all is collective  data.max_corner = max_to_all(data.max_corner);  data.min_corner = -max_to_all(-data.min_corner); // i.e., min_to_all  data.num_chunks = sum_to_all(data.num_chunks);  if (data.num_chunks == 0 || !(data.min_corner <= data.max_corner))    return; // no data to write;  int rank = 0, dims[3];  LOOP_OVER_DIRECTIONS(v.dim, d) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -